--- /dev/null
+/*****************************************************************************
+ * video_decoder.h : video decoder thread
+ * (c)1999 VideoLAN
+ *****************************************************************************
+ *****************************************************************************
+ * Requires:
+ * "config.h"
+ * "common.h"
+ * "mtime.h"
+ * "vlc_thread.h"
+ * "input.h"
+ * "video.h"
+ * "video_output.h"
+ * "decoder_fifo.h"
+ *****************************************************************************/
+
+/*****************************************************************************
+ * vdec_thread_t: video decoder thread descriptor
+ *****************************************************************************
+ * ??
+ *****************************************************************************/
+typedef struct vdec_thread_s
+{
+ /* Thread properties and locks */
+ boolean_t b_die; /* `die' flag */
+ boolean_t b_run; /* `run' flag */
+ boolean_t b_error; /* `error' flag */
+ boolean_t b_active; /* `active' flag */
+ vlc_thread_t thread_id; /* id for thread functions */
+
+ /* Thread configuration */
+ /* ?? */
+ /*??*/
+// int *pi_status;
+
+
+ /* Input properties */
+ video_parser_t * p_vpar; /* video_parser thread */
+
+#ifdef STATS
+ /* Statistics */
+ count_t c_loops; /* number of loops */
+ count_t c_idle_loops; /* number of idle loops */
+ count_t c_decoded_pictures; /* number of pictures decoded */
+ count_t c_decoded_i_pictures; /* number of I pictures decoded */
+ count_t c_decoded_p_pictures; /* number of P pictures decoded */
+ count_t c_decoded_b_pictures; /* number of B pictures decoded */
+#endif
+} vdec_thread_t;
+
+/*****************************************************************************
+ * Prototypes
+ *****************************************************************************/
+
+/* Thread management functions */
+vdec_thread_t * vdec_CreateThread ( vpar_thread_t *p_vpar /*, int *pi_status */ );
+void vdec_DestroyThread ( vdec_thread_t *p_vdec /*, int *pi_status */ );
+
+/* Time management functions */
+/* ?? */
+
+/* Dynamic thread settings */
+/* ?? */
/*****************************************************************************
* video_fifo_t
*****************************************************************************
- * This rotative FIFO contains undecoded pictures that are to be decoded
+ * This rotative FIFO contains undecoded macroblocks that are to be decoded
*****************************************************************************/
typedef struct video_fifo_s
{
vlc_cond_t wait; /* fifo data conditional variable */
/* buffer is an array of undec_picture_t pointers */
- undec_picture_t * buffer[VFIFO_SIZE + 1];
+ macroblock_t * buffer[VFIFO_SIZE + 1];
int i_start;
int i_end;
* video_buffer_t
*****************************************************************************
* This structure enables the parser to maintain a list of free
- * undec_picture_t structures
+ * macroblock_t structures
*****************************************************************************/
typedef struct video_buffer_s
{
vlc_mutex_t lock; /* buffer data lock */
- undec_picture_t p_undec_p[VFIFO_SIZE + 1];
- undec_picture_t * pp_undec_free[VFIFO_SIZE+1]; /* this is a LIFO */
+ macroblock_t p_macroblocks[VFIFO_SIZE + 1];
+ macroblock_t * pp_mb_free[VFIFO_SIZE+1]; /* this is a LIFO */
int i_index;
} video_buffer_t;
/*****************************************************************************
* Prototypes
*****************************************************************************/
-undec_picture_t * vpar_GetPicture( video_fifo_t * p_fifo );
-undec_picture_t * vpar_NewPicture( video_fifo_t * p_fifo );
-void vpar_DecodePicture( video_fifo_t * p_fifo, undec_picture_t * p_undec_p );
-void vpar_ReleasePicture( video_fifo_t * p_fifo, undec_picture_t * p_undec_p );
-void vpar_DestroyPicture( video_fifo_t * p_fifo, undec_picture_t * p_undec_p );
+macroblock_t * vpar_GetMacroblock( video_fifo_t * p_fifo );
+macroblock_t * vpar_NewMacroblock( video_fifo_t * p_fifo );
+void vpar_DecodeMacroblock( video_fifo_t * p_fifo, macroblock_t * p_mb );
+void vpar_ReleaseMacroblock( video_fifo_t * p_fifo, macroblock_t * p_mb );
+void vpar_DestroyMacroblock( video_fifo_t * p_fifo, macroblock_t * p_mb );
-/*******************************************************************************
+/*****************************************************************************
* video_parser.h : video parser thread
* (c)1999 VideoLAN
- *******************************************************************************
- *******************************************************************************
+ *****************************************************************************
+ *****************************************************************************
* Requires:
* "config.h"
* "common.h"
* "video_output.h"
* "decoder_fifo.h"
* "video_fifo.h"
- *******************************************************************************/
+ * "vpar_headers.h"
+ *****************************************************************************/
-/*******************************************************************************
- * sequence_t : sequence descriptor
- *******************************************************************************
- * ??
- *******************************************************************************/
-typedef struct sequence_s
-{
- u16 i_height, i_width;
- u16 i_mb_height, i_mb_width;
- unsigned int i_aspect_ratio;
- double d_frame_rate;
- unsigned int i_chroma_format;
- boolean_t b_mpeg2;
- boolean_t b_progressive;
-
- /* Parser context */
- picture_t * p_forward, p_backward;
- pel_lookup_table_t * p_frame_lum_lookup, p_field_lum_lookup;
- pel_lookup_table_t * p_frame_chroma_lookup, p_field_chroma_lookup;
- quant_matrix_t intra_quant, nonintra_quant;
- quant_matrix_t chroma_intra_quant, chroma_nonintra_quant;
-} sequence_t;
-
-/*******************************************************************************
+/*****************************************************************************
* vpar_thread_t: video parser thread descriptor
- *******************************************************************************
+ *****************************************************************************
* ??
- *******************************************************************************/
+ *****************************************************************************/
typedef struct vpar_thread_s
{
/* Thread properties and locks */
- boolean_t b_die; /* `die' flag */
- boolean_t b_run; /* `run' flag */
- boolean_t b_error; /* `error' flag */
- boolean_t b_active; /* `active' flag */
- vlc_thread_t thread_id; /* id for thread functions */
+ boolean_t b_die; /* `die' flag */
+ boolean_t b_run; /* `run' flag */
+ boolean_t b_error; /* `error' flag */
+ boolean_t b_active; /* `active' flag */
+ vlc_thread_t thread_id; /* id for thread functions */
/* Thread configuration */
/* ?? */
/* Input properties */
- decoder_fifo_t fifo; /* PES input fifo */
+ decoder_fifo_t fifo; /* PES input fifo */
/* The bit stream structure handles the PES stream at the bit level */
bit_stream_t bit_stream;
/* Output properties */
- vout_thread_t * p_vout; /* video output thread */
- int i_stream; /* video stream id */
+ vout_thread_t * p_vout; /* video output thread */
+ int i_stream; /* video stream id */
/* Decoder properties */
- struct vdec_thread_s * p_vdec[MAX_VDEC];
+ struct vdec_thread_s * p_vdec[NB_VDEC];
video_fifo_t vfifo;
video_buffer_t vbuffer;
/* Parser properties */
- sequence_t sequence;
+ sequence_t sequence;
+ picture_parsing_t picture;
+ slice_parsing_t slice;
+ macroblock_parsing_t mb;
#ifdef STATS
/* Statistics */
- count_t c_loops; /* number of loops */
- count_t c_idle_loops; /* number of idle loops */
- count_t c_sequences; /* number of sequences */
- count_t c_pictures; /* number of pictures read */
- count_t c_i_pictures; /* number of I pictures read */
- count_t c_p_pictures; /* number of P pictures read */
- count_t c_b_pictures; /* number of B pictures read */
- count_t c_decoded_pictures; /* number of pictures decoded */
- count_t c_decoded_i_pictures; /* number of I pictures decoded */
- count_t c_decoded_p_pictures; /* number of P pictures decoded */
- count_t c_decoded_b_pictures; /* number of B pictures decoded */
+ count_t c_loops; /* number of loops */
+ count_t c_idle_loops; /* number of idle loops */
+ count_t c_sequences; /* number of sequences */
+ count_t c_pictures; /* number of pictures read */
+ count_t c_i_pictures; /* number of I pictures read */
+ count_t c_p_pictures; /* number of P pictures read */
+ count_t c_b_pictures; /* number of B pictures read */
+ count_t c_decoded_pictures; /* number of pictures decoded */
+ count_t c_decoded_i_pictures; /* number of I pictures decoded */
+ count_t c_decoded_p_pictures; /* number of P pictures decoded */
+ count_t c_decoded_b_pictures; /* number of B pictures decoded */
#endif
} vpar_thread_t;
-/*******************************************************************************
- * Standard start codes
- *******************************************************************************/
-#define PICTURE_START_CODE 0x100
-#define SLICE_START_CODE_MIN 0x101
-#define SLICE_START_CODE_MAX 0x1AF
-#define USER_DATA_START_CODE 0x1B2
-#define SEQUENCE_HEADER_CODE 0x1B3
-#define SEQUENCE_ERROR_CODE 0x1B4
-#define EXTENSION_START_CODE 0x1B5
-#define SEQUENCE_END_CODE 0x1B7
-#define GROUP_START_CODE 0x1B8
-
-/* extension start code IDs */
-
-#define SEQUENCE_EXTENSION_ID 1
-#define SEQUENCE_DISPLAY_EXTENSION_ID 2
-#define QUANT_MATRIX_EXTENSION_ID 3
-#define COPYRIGHT_EXTENSION_ID 4
-#define SEQUENCE_SCALABLE_EXTENSION_ID 5
-#define PICTURE_DISPLAY_EXTENSION_ID 7
-#define PICTURE_CODING_EXTENSION_ID 8
-#define PICTURE_SPATIAL_SCALABLE_EXTENSION_ID 9
-#define PICTURE_TEMPORAL_SCALABLE_EXTENSION_ID 10
-
-/*******************************************************************************
+/*****************************************************************************
* Prototypes
- *******************************************************************************/
+ *****************************************************************************/
/* Thread management functions */
vpar_thread_t * vpar_CreateThread ( /* video_cfg_t *p_cfg, */ input_thread_t *p_input /*,
*****************************************************************************/
/*****************************************************************************
- * quant_matrix_t : Quantization Matrix
+ * macroblock_t : information on a macroblock
+ *****************************************************************************/
+typedef struct macroblock_s
+{
+ picture_t * p_picture;
+ int i_mb_x, i_mb_y;
+ int i_structure;
+ int i_l_x, i_l_y; /* position of macroblock (lum) */
+ int i_c_x, i_c_y; /* position of macroblock (chroma) */
+ int i_structure;
+ int i_chroma_nb_blocks; /* nb of bks for a chr comp */
+
+ /* IDCT information */
+ elem_t ppi_blocks[12][64]; /* blocks */
+ f_idct_t pf_idct[12]; /* sparse IDCT or not ? */
+ int pi_sparse_pos[12];
+
+ /* Motion compensation information */
+ f_motion_t pf_motion; /* function to use for motion comp */
+ f_chroma_motion_t pf_chroma_motion;
+ picture_t * p_backw_top, p_backw_bot;
+ picture_t * p_forw_top, p_forw_bot;
+ int i_field_select_backw_top, i_field_select_backw_bot;
+ int i_field_select_forw_top, i_field_select_forw_bot;
+ int pi_motion_vectors_backw_top[2];
+ int pi_motion_vectors_backw_bot[2];
+ int pi_motion_vectors_forw_top[2];
+ int pi_motion_vectors_forw_bot[2];
+
+ /* AddBlock information */
+ f_addb_t pf_addb[12];
+ data_t * p_data[12]; /* positions of blocks in picture */
+ int i_lum_incr, i_chroma_incr;
+} macroblock_t;
+
+/*****************************************************************************
+ * macroblock_parsing_t : parser context descriptor #3
+ *****************************************************************************/
+typedef struct
+{
+ int i_mb_type, i_motion_type, i_mv_count, i_mv_format;
+ int i_coded_block_pattern;
+ boolean_t b_dct_type;
+} macroblock_parsing_t;
+
+/*****************************************************************************
+ * LoadQuantizerScale
*****************************************************************************
- * ??
+ * Quantizer scale factor (ISO/IEC 13818-2 7.4.2.2)
*****************************************************************************/
-typedef struct quant_matrix_s
+static __inline__ void LoadQuantizerScale( vpar_thread_t * p_vpar )
{
- int pi_matrix[64];
- boolean_t b_allocated;
- /* Has the matrix been allocated by vpar_headers ? */
-} quant_matrix_t;
+ /* Quantization coefficient table */
+ static unsigned char ppi_quantizer_scale[3][32] =
+ {
+ /* MPEG-2 */
+ {
+ /* q_scale_type */
+ /* linear */
+ 0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,
+ 32,34,36,38,40,42,44,46,48,50,52,54,56,58,60,62
+ },
+ {
+ /* non-linear */
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 10,12,14,16,18,20, 22,
+ 24,28,32,36,40,44,48,52,56,64,72,80,88,96,104,112
+ },
+ /* MPEG-1 */
+ {
+ 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
+ 16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31
+ }
+ };
+
+ p_vpar->slice.i_quantizer_scale = ppi_quantizer_scale
+ [(!p_vpar->sequence.b_mpeg2 << 1) | p_vpar->picture.b_q_scale_type]
+ [GetBits( &p_vpar->bit_stream, 5 )];
+}
+
+/*****************************************************************************
+ * Standard codes
+ *****************************************************************************/
+/* Macroblock types */
+#define MB_INTRA 1
+#define MB_PATTERN 2
+#define MB_MOTION_BACKWARD 4
+#define MB_MOTION_FORWARD 8
+#define MB_QUANT 16
-extern int * pi_default_intra_quant;
-extern int * pi_default_nonintra_quant;
+/* Motion types */
+#define MOTION_FIELD 1
+#define MOTION_FRAME 2
+#define MOTION_16X8 2
+#define MOTION_DMV 3
--- /dev/null
+/*****************************************************************************
+ * vpar_headers.h : video parser : headers parsing
+ * (c)1999 VideoLAN
+ *****************************************************************************
+ *****************************************************************************
+ * Requires:
+ * "config.h"
+ * "common.h"
+ * "mtime.h"
+ * "vlc_thread.h"
+ * "input.h"
+ * "video.h"
+ * "video_output.h"
+ * "decoder_fifo.h"
+ * "video_fifo.h"
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Function pointers
+ *****************************************************************************/
+typedef (void *) f_slice_header_t( vpar_thread_t*, int*, int, elem_t*, u32);
+
+/*****************************************************************************
+ * quant_matrix_t : Quantization Matrix
+ *****************************************************************************/
+typedef struct quant_matrix_s
+{
+ int pi_matrix[64];
+ boolean_t b_allocated;
+ /* Has the matrix been allocated by vpar_headers ? */
+} quant_matrix_t;
+
+extern int * pi_default_intra_quant;
+extern int * pi_default_nonintra_quant;
+
+/*****************************************************************************
+ * sequence_t : sequence descriptor
+ *****************************************************************************/
+typedef struct sequence_s
+{
+ u32 i_height, i_width, i_chroma_width, i_size;
+ u32 i_mb_height, i_mb_width, i_mb_size;
+ unsigned int i_aspect_ratio;
+ double d_frame_rate;
+ unsigned int i_chroma_format;
+ int i_chroma_nb_blocks;
+ boolean_t b_mpeg2;
+ boolean_t b_progressive;
+ unsigned int i_scalable_mode;
+ f_slice_header_t pf_slice_header;
+ quant_matrix_t intra_quant, nonintra_quant;
+ quant_matrix_t chroma_intra_quant, chroma_nonintra_quant;
+ (void *) pf_decode_mv( vpar_thread_t *, int );
+ (void *) pf_decode_pattern( vpar_thread_t * );
+
+ /* Parser context */
+ picture_t * p_forward, p_backward;
+} sequence_t;
+
+/*****************************************************************************
+ * picture_parsing_t : parser context descriptor
+ *****************************************************************************/
+typedef struct picture_parsing_s
+{
+ boolean_t b_full_pel_forward_vector, b_full_pel_backward_vector;
+ int i_forward_f_code, i_backward_f_code;
+
+ int ppi_f_code[2][2];
+ int i_intra_dc_precision;
+ boolean_t b_frame_pred_frame_dct, b_q_scale_type;
+ boolean_t b_alternate_scan, b_progressive_frame;
+ boolean_t b_top_field_first, b_concealment_mv;
+
+ int i_lum_incr, i_chroma_incr;
+
+ /* Used for second field management */
+ int i_current_structure;
+
+ picture_t * p_picture;
+ macroblock_t * pp_mb[MAX_MB];
+
+ /* Relative to the current field */
+ int i_coding_type, i_structure;
+ boolean_t b_frame_structure;
+ (int *) pf_macroblock_type( vpar_thread_t * );
+
+ boolean_t b_error;
+} picture_parsing_t;
+
+/*****************************************************************************
+ * slice_parsing_t : parser context descriptor #2
+ *****************************************************************************/
+typedef struct slice_parsing_s
+{
+ unsigned char i_quantizer_scale;
+ int pi_dc_dct_pred[3]; /* ISO/IEC 13818-2 7.2.1 */
+ int pppi_pmv[2][2][2]; /* Motion vect predictors, 7.6.3 */
+} slice_parsing_t;
+
+/*****************************************************************************
+ * Standard codes
+ *****************************************************************************/
+#define PICTURE_START_CODE 0x100
+#define SLICE_START_CODE_MIN 0x101
+#define SLICE_START_CODE_MAX 0x1AF
+#define USER_DATA_START_CODE 0x1B2
+#define SEQUENCE_HEADER_CODE 0x1B3
+#define SEQUENCE_ERROR_CODE 0x1B4
+#define EXTENSION_START_CODE 0x1B5
+#define SEQUENCE_END_CODE 0x1B7
+#define GROUP_START_CODE 0x1B8
+
+/* extension start code IDs */
+#define SEQUENCE_EXTENSION_ID 1
+#define SEQUENCE_DISPLAY_EXTENSION_ID 2
+#define QUANT_MATRIX_EXTENSION_ID 3
+#define COPYRIGHT_EXTENSION_ID 4
+#define SEQUENCE_SCALABLE_EXTENSION_ID 5
+#define PICTURE_DISPLAY_EXTENSION_ID 7
+#define PICTURE_CODING_EXTENSION_ID 8
+#define PICTURE_SPATIAL_SCALABLE_EXTENSION_ID 9
+#define PICTURE_TEMPORAL_SCALABLE_EXTENSION_ID 10
+
+/* scalable modes */
+#define SC_NONE 0
+#define SC_DP 1
+#define SC_SPAT 2
+#define SC_SNR 3
+#define SC_TEMP 4
+
+/* Pictures types */
+#define I_CODING_TYPE 1
+#define P_CODING_TYPE 2
+#define B_CODING_TYPE 3
+#define D_CODING_TYPE 4 /* MPEG-1 ONLY */
+/* other values are reserved */
+
+/* Structures */
+#define TOP_FIELD 1
+#define BOTTOM_FIELD 2
+#define FRAME_STRUCTURE 3
--- /dev/null
+/*****************************************************************************
+ * vdec_idct.c : IDCT functions
+ * (c)1999 VideoLAN
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Preamble
+ *****************************************************************************/
+#include <errno.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/uio.h>
+#include <X11/Xlib.h>
+#include <X11/extensions/XShm.h>
+
+#include "config.h"
+#include "common.h"
+#include "mtime.h"
+#include "vlc_thread.h"
+
+#include "intf_msg.h"
+#include "debug.h" /* ?? temporaire, requis par netlist.h */
+
+#include "input.h"
+#include "input_netlist.h"
+#include "decoder_fifo.h"
+#include "video.h"
+#include "video_output.h"
+#include "video_parser.h"
+
+#include "undec_picture.h"
+#include "video_fifo.h"
+#include "video_decoder.h"
+
+/*
+ * Local prototypes
+ */
+
+/* Our current implementation is a fast DCT, we might move to a fast DFT or
+ * an MMX DCT in the future. */
+
+/*****************************************************************************
+ * vdec_DummyIDCT : dummy function that does nothing
+ *****************************************************************************/
+void vdec_DummyIDCT( elem_t * p_block, int i_idontcare )
+{
+}
+
+/*****************************************************************************
+ * vdec_SparseIDCT : IDCT function for sparse matrices
+ *****************************************************************************/
+void vdec_SparseIDCT( elem_t * p_block, int i_sparse_pos )
+{
+ /* Copy from mpeg_play */
+}
+
+/*****************************************************************************
+ * vdec_IDCT : IDCT function for normal matrices
+ *****************************************************************************/
+void vdec_IDCT( elem_t * p_block, int i_idontcare )
+{
+
+}
* (c)1999 VideoLAN
*****************************************************************************/
-/* ?? passer en terminate/destroy avec les signaux supplémentaires */
-
/*****************************************************************************
* Preamble
*****************************************************************************/
* Local prototypes
*/
+typedef (void *) f_motion_c_t( coeff_t *, pel_lookup_table_t *,
+ int, coeff_t *, int, int,
+ int, int, int, int, int );
+
/*****************************************************************************
- * vdec_MotionCompensation : motion compensation
+ * vdec_DummyRecon : motion compensation for an intra macroblock
*****************************************************************************/
-void vdec_MotionFrame( vdec_thread_t * p_vdec,
- undec_picture_t * p_undec_p, int i_mb,
- f_motion_mb_t pf_mb_motion )
+void vdec_DummyRecon( macroblock_t * p_mb )
{
- static int p_chroma_nb_blocks[4] = {1, 2, 4};
- static int p_chroma_nb_elems[4] = {0, 64, 128, 256};
+}
- int i_mb_x, i_mb_y; /* Position of our macroblock in the final picture */
- elem_t * p_y, p_u, p_v; /* Pointers to our picture's data */
+/*****************************************************************************
+ * vdec_ForwardRecon : motion compensation for a forward predicted macroblock
+ *****************************************************************************/
+void vdec_ForwardRecon( macroblock_t * p_mb )
+{
+
+}
+
+/*****************************************************************************
+ * vdec_BackwardRecon : motion compensation for a backward predicted macroblock
+ *****************************************************************************/
+void vdec_BackwardRecon( macroblock_t * p_mb )
+{
-#define P_mb_info p_undec_p->p_mb_info[i_mb]
-
- i_mb_x = (i_mb << 5) % p_undec_p->p_picture->i_width;
- i_mb_y = (i_mb << 5) / p_undec_p->p_picture->i_width;
- p_y = &p_undec_p->p_picture->p_y[256*i_mb];
- p_u = &p_undec_p->p_picture->p_u[p_chroma_nb_elems[p_undec_p->p_picture->i_chroma_type]*i_mb];
- p_v = &p_undec_p->p_picture->p_v[p_chroma_nb_elems[p_undec_p->p_picture->i_chroma_type]*i_mb];
-
- if( (p_undec_p->i_coding_type == P_CODING_TYPE) ||
- (P_mb_info->i_mb_type & MB_MOTION_FORWARD) )
- {
- if( (P_mb_info->i_motion_type == MOTION_FRAME) ||
- !(P_mb_info->i_mb_type & MB_INTRA) )
- {
- MotionBlock( p_undec_p->p_forward->p_u,
- p_undec_p->p_forward->p_lookup_lum,
- p_undec_p->p_picture->i_width,
- p_u, i_mb_x, i_mb_y,
- p_undec_p->p_picture->i_width,
- p_undec_p->ppp_motion_vectors[0][0][0],
- p_undec_p->ppp_motion_vectors[0][0][1] );
- }
- }
}
/*****************************************************************************
- * MotionMacroblock : motion compensation for a macroblock
+ * vdec_BidirectionalRecon : motion compensation for a bidirectionally
+ * predicted macroblock
*****************************************************************************/
-void vdec_MotionMacroblock420( coeff_t * p_src, pel_lookup_table_t * p_lookup,
- int i_width_line,
- coeff_t * p_dest, int i_dest_x, i_dest_y,
- int i_stride_line,
- i_mv1_x, i_mv1_y, i_mv2_x, i_mv2_y )
+void vdec_BidirectionalRecon( macroblock_t * p_mb )
+{
+
+}
+
+/*****************************************************************************
+ * vdec_MotionMacroblock420 : motion compensation for a 4:2:0 macroblock
+ *****************************************************************************/
+void vdec_MotionMacroblock420( macroblock_t * p_mb )
{
/* Luminance */
MotionBlock( p_undec_p->p_forward->p_u, p_undec_p->p_forward->p_lookup_lum,
int i_stride_line,
i_mv1_x, i_mv1_y, i_mv2_x, i_mv2_y )
{
- static (void *) ComponentMode( coeff_t * p_src,
- pel_lookup_table_t * p_lookup,
- coeff_t * p_dest, int i_dest_x, i_dest_y,
- int i_stride_line, i_mv_x, i_mv_y )[4]
- = { ComponentNN, ComponentNH, ComponentHN,
- ComponentHH };
+ static f_motion_c_t ComponentMode[4]
+ = { &ComponentNN, &ComponentNH, &ComponentHN,
+ &ComponentHH };
int i_mode;
ComponentMode[i_mode]( p_src, p_lookup, i_width_line,
p_dest, i_dest_x, i_dest_y,
- i_stride_line, i_mv_x >> 1, i_mv_y >> 1 );
+ i_stride_line, i_mv1_x >> 1, i_mv1_y >> 1,
+ i_mv2_x >> 1, i_mv2_y >> 1 );
}
/*****************************************************************************
int i_vpos;
register int i_hpos, i_src_loc;
- i_src_loc = (i_dest_y + i_mv_y)*i_width_line + i_dest_x + i_mv_x;
+ i_src_loc = (i_dest_y + i_mv1_y)*i_width_line + i_dest_x + i_mv1_x;
- for( i_vpos = 0; i_vpos < 8; i_vpos++ )
+ for( i_vpos = 0; i_vpos < 4; i_vpos++ )
+ {
+ for( i_hpos = 0; i_hpos < 8; i_hpos++ )
+ {
+ p_dest[i_hpos] += p_src[p_lookup->pi_pel[i_src_loc + i_hpos]];
+ }
+
+ p_dest += 8;
+ i_src_loc += i_stride_line;
+ }
+
+ i_src_loc = (i_dest_y + i_mv2_y)*i_width_line + i_dest_x + i_mv2_x;
+
+ for( i_vpos = 4; i_vpos < 8; i_vpos++ )
{
for( i_hpos = 0; i_hpos < 8; i_hpos++ )
{
static void RunThread ( vdec_thread_t *p_vdec );
static void ErrorThread ( vdec_thread_t *p_vdec );
static void EndThread ( vdec_thread_t *p_vdec );
-static void DecodePicture ( vdec_thread_t *p_vdec,
- undec_picture_t * p_undec_p );
+static void DecodeMacroblock ( vdec_thread_t *p_vdec,
+ macroblock_t * p_mb );
/*******************************************************************************
* vdec_CreateThread: create a video decoder thread
*/
while( (!p_vdec->b_die) && (!p_vdec->b_error) )
{
- undec_picture_t * p_undec_p;
+ macroblock_t * p_mb;
- if( (p_undec_p = GetPicture( p_vdec->p_vpar->p_fifo )) != NULL )
+ if( (p_mb = GetMacroblock( &p_vdec->p_vpar.vfifo )) != NULL )
{
- DecodePicture( p_vdec, p_undec_p );
+ DecodeMacroblock( p_vdec, p_mb );
}
}
}
/*******************************************************************************
- * DecodePicture : decode a picture
+ * DecodeMacroblock : decode a macroblock of a picture
*******************************************************************************/
-static void DecodePicture( vdec_thread_t *p_vdec, undec_picture_t * p_undec_p )
+static void DecodeMacroblock( vdec_thread_t *p_vdec, macroblock_t * p_mb )
{
- static int pi_chroma_nb_blocks[4] = {0, 1, 2, 4};
- static int pi_chroma_nb_coeffs[4] = {0, 64, 128, 256};
- static f_motion_mb_t ppf_chroma_motion[4] = { NULL,
- &vdec_MotionMacroBlock420,
- &vdec_MotionMacroBlock422,
- &vdec_MotionMacroBlock444 };
- static f_motion_t pppf_motion_forward[4][2] = {
- {NULL, NULL} /* I picture */
- {&vdec_MotionForward, &vdec_MotionForward} /* P */
- {NULL, &vdec_MotionForward} /* B */
- {NULL, NULL} /* D */ };
- static f_motion_t pppf_motion_backward[4][2] = {
- {NULL, NULL} /* I picture */
- {NULL, NULL} /* P */
- {NULL, &vdec_MotionBackward} /* B */
- {NULL, NULL} /* D */ };
- static f_motion_t ppf_motion[4] = { NULL,
- &vdec_MotionTopFirst,
- &vdec_MotionBottomFirst,
- &vdec_MotionFrame };
-
- int i_mb, i_b, i_totb;
- coeff_t * p_y, p_u, p_v;
- f_motion_mb_t pf_chroma_motion;
- f_motion_t pf_motion_forward, pf_motion_backward;
- int i_chroma_nb_blocks, i_chroma_nb_coeffs;
-
- p_y = (coeff_t *)p_undec_p->p_picture->p_y;
- p_u = (coeff_t *)p_undec_p->p_picture->p_u;
- p_v = (coeff_t *)p_undec_p->p_picture->p_v;
-
-#define I_chroma_format p_undec_p->p_picture->i_chroma_format
- pf_chroma_motion = ppf_chroma_motion[I_chroma_format];
- pf_motion_forward
- pf_motion = ppf_motion[p_undec_p->i_structure];
+ int i_b;
- i_chroma_nb_blocks = pi_chroma_nb_blocks[I_chroma_format];
- i_chroma_nb_coeffs = pi_chroma_nb_coeffs[I_chroma_format];
-#undef I_chroma_format
+ /*
+ * Motion Compensation (ISO/IEC 13818-2 section 7.6)
+ */
+ (*p_mb->pf_motion)( p_mb );
- for( i_mb = 0; i_mb < p_undec_p->i_mb_height*p_undec_p->i_mb_width; i_mb++ )
+ /* luminance */
+ for( i_b = 0; i_b < 4; i_b++ )
{
-#define P_mb_info p_undec_p->p_mb_info[i_ref]
-
/*
* Inverse DCT (ISO/IEC 13818-2 section Annex A)
*/
-
- /* Luminance : always 4 blocks */
- for( i_b = 0; i_b < 4; i_b++ )
- {
- (*P_mb_info.p_idct_function[i_b])( p_y + i_b*64 );
- }
- i_totb = 4;
-
- /* Chrominance Cr */
- for( i_b = 0; i_b < i_chroma_nb_blocks\ 5; i_b++ )
- {
- (*P_mb_info.p_idct_function[i_totb + i_b])( p_u + i_b*64 );
- }
- i_totb += i_chroma_nb_blocks;
-
- /* Chrominance Cb */
- for( i_b = 0; i_b < i_chroma_nb_blocks; i_b++ )
- {
- (*P_mb_info.p_idct_function[i_totb + i_b])( p_v + i_b*64 );
- }
+ (*p_mb->pf_idct[i_b])( p_mb, p_mb->ppi_blocks[i_b], p_mb->pi_sparse_pos[i_b] );
+
+ /*
+ * Adding prediction and coefficient data (ISO/IEC 13818-2 section 7.6.8)
+ */
+ (*p_mb->pf_addb[i_b])( p_mb->ppi_blocks[i_b],
+ p_mb->p_data[i_b], p_mb->i_lum_incr );
+ }
+ /* chrominance */
+ for( i_b = 4; i_b < 4 + 2*p_mb->i_chroma_nb_blocks; i_b++ )
+ {
/*
- * Motion Compensation (ISO/IEC 13818-2 section 7.6)
+ * Inverse DCT (ISO/IEC 13818-2 section Annex A)
*/
- (*pf_motion)( p_vdec, p_undec_p, i_mb, pf_chroma_motion );
+ (*p_mb->pf_idct[i_b])( p_mb, p_mb->ppi_blocks[i_b], p_mb->pi_sparse_pos[i_b] );
- p_y += 256;
- p_u += i_chroma_nb_coeffs;
- p_v += i_chroma_nb_coeffs;
-#undef P_mb_info
+ /*
+ * Adding prediction and coefficient data (ISO/IEC 13818-2 section 7.6.8)
+ */
+ (*p_mb->pf_addb[i_b])( p_mb->ppi_blocks[i_b],
+ p_mb->p_data[i_b], p_mb->i_chroma_incr );
}
/*
- * Decoding is finished, mark the picture ready for displaying and free
- * unneeded memory
+ * Decoding is finished, release the macroblock and free
+ * unneeded memory.
*/
- vpar_ReleasePicture( p_vdec->p_vpar->p_fifo, p_undec_p );
+ vpar_ReleaseMacroblock( &p_vdec->p_vpar.vfifo, p_mb );
+}
+
+/*******************************************************************************
+ * vdec_AddBlock : add a block
+ *******************************************************************************/
+void vdec_AddBlock( elem_t * p_block, data_t * p_data, int i_incr )
+{
+ int i_x, i_y;
+
+ for( i_y = 0; i_y < 8; i_y++ )
+ {
+ for( i_x = 0; i_x < 8; i_x++ )
+ {
+ /* ??? Need clip to be MPEG-2 compliant */
+ *p_data++ += *p_block++;
+ }
+ p_data += i_incr;
+ }
+}
+
+/*******************************************************************************
+ * vdec_CopyBlock : copy a block
+ *******************************************************************************/
+void vdec_CopyBlock( elem_t * p_block, data_t * p_data, int i_incr )
+{
+ int i_x, i_y;
+
+ for( i_y = 0; i_y < 8; i_y++ )
+ {
+#ifndef VDEC_DFT
+ /* elem_t and data_t are the same */
+ memcopy( p_data, p_block, 8*sizeof(data_t) );
+ p_data += i_incr+8;
+ p_block += 8;
+#else
+ for( i_x = 0; i_x < 8; i_x++ )
+ {
+ /* ??? Need clip to be MPEG-2 compliant */
+ /* ??? Why does the reference decoder add 128 ??? */
+ *p_data++ = *p_block++;
+ }
+ p_data += i_incr;
+#endif
+ }
+}
+
+/*******************************************************************************
+ * vdec_DummyBlock : dummy function that does nothing
+ *******************************************************************************/
+void vdec_DummyBlock( elem_t * p_block, data_t * p_data, int i_incr )
+{
}
#include "video_output.h"
#include "video_parser.h"
-#include "undec_picture.h"
+#include "macroblock.h"
#include "video_fifo.h"
#include "video_decoder.h"
*****************************************************************************/
void vpar_InitFIFO( vpar_thread_t * p_vpar )
{
- int i_dummy;
+ int i_dummy;
/* Initialize mutex and cond */
vlc_mutex_init( p_vpar->vfifo.lock );
i_index = VFIFO_SIZE; /* all structures are available */
for( i_dummy = 0; i_dummy < VFIFO_SIZE + 1; i_dummy++ )
{
- p_vpar->vfifo.pp_undec_free[i_dummy] = p_vpar->vfifo.p_undec_p + i;
- p_vpar->vfifo.p_undec_p[i].p_mb_info = NULL;
+ p_vpar->vfifo.pp_mb_free[i_dummy] = p_vpar->vfifo.p_macroblocks + i;
}
}
/*****************************************************************************
- * vpar_GetPicture : return a picture to be decoded
+ * vpar_GetMacroblock : return a macroblock to be decoded
*****************************************************************************/
-undec_picture_t * vpar_GetPicture( video_fifo_t * p_fifo )
+macroblock_t * vpar_GetMacroblock( video_fifo_t * p_fifo )
{
- undec_picture_t * p_undec_p;
+ macroblock_t * p_mb;
vlc_mutex_lock( &p_fifo->lock );
while( VIDEO_FIFO_ISEMPTY( *p_fifo ) )
}
}
- p_undec_p = VIDEO_FIFO_START( *p_fifo );
+ p_mb = VIDEO_FIFO_START( *p_fifo );
VIDEO_FIFO_INCSTART( *p_fifo );
vlc_mutex_unlock( &p_fifo->lock );
- return( p_undec_p );
+ return( p_mb );
}
/*****************************************************************************
- * vpar_NewPicture : return a buffer for the parser
+ * vpar_NewMacroblock : return a buffer for the parser
*****************************************************************************/
-undec_picture_t * vpar_NewPicture( video_fifo_t * p_fifo )
+macroblock_t * vpar_NewMacroblock( video_fifo_t * p_fifo )
{
- undec_picture_t * p_undec_p;
+ macroblock_t * p_mb;
#define P_buffer p_fifo->p_vpar.vbuffer
vlc_mutex_lock( &P_buffer->lock );
return NULL;
}
- p_undec_p = P_buffer->pp_undec_free[ P_buffer->i_index-- ];
+ p_mb = P_buffer->pp_undec_free[ P_buffer->i_index-- ];
#undef P_buffer
vlc_mutex_unlock( &P_buffer->lock );
- return( p_undec_p );
+ return( p_mb );
}
/*****************************************************************************
- * vpar_DecodePicture : put a picture in the video fifo, if it is decodable
+ * vpar_DecodeMacroblock : put a macroblock in the video fifo
*****************************************************************************/
-void vpar_DecodePicture( video_fifo_t * p_fifo, undec_picture_t * p_undec_p )
+void vpar_DecodeMacroblock( video_fifo_t * p_fifo, macroblock_t * p_mb )
{
- boolean_t b_decodable;
-
- switch( p_undec_p )
- {
- case B_CODING_TYPE:
- b_decodable = ((p_undec_p->p_backward_p != NULL) &&
- (p_undec_p->p_forward_p != NULL));
- break;
- case P_CODING_TYPE:
- b_decodable = (p_undec_p->p_backward_p != NULL);
- break;
- case I_CODING_TYPE:
- case D_CODING_TYPE:
- b_decodable = TRUE;
- break;
- default:
- /* That should not happen */
- }
-
- if( b_decodable )
- {
- /* Place picture in the video FIFO */
- vlc_mutex_lock( &p_fifo->lock );
+ /* Place picture in the video FIFO */
+ vlc_mutex_lock( &p_fifo->lock );
- /* By construction, the video FIFO cannot be full */
- VIDEO_FIFO_END( *p_fifo ) = p_undec_p;
- VIDEO_FIFO_INCEND( *p_fifo );
+ /* By construction, the video FIFO cannot be full */
+ VIDEO_FIFO_END( *p_fifo ) = p_mb;
+ VIDEO_FIFO_INCEND( *p_fifo );
- vlc_mutex_unlock( &p_fifo->lock );
- }
+ vlc_mutex_unlock( &p_fifo->lock );
}
/*****************************************************************************
- * vpar_ReleasePicture : put a picture in the video_output fifo, and update
- * links and buffers
+ * vpar_ReleaseMacroblock : release a macroblock and put the picture in the
+ * video output heap, if it is finished
*****************************************************************************/
-void vpar_ReleasePicture( video_fifo_t * p_fifo, undec_picture_t * p_undec_p )
+void vpar_ReleaseMacroblock( video_fifo_t * p_fifo, macroblock_t * p_mb )
{
- int i_ref;
-
- /* Tell referencing pictures so that they can be decoded */
- for( i_ref = 0; p_undec_p->pp_referencing_undec[i_ref].p_undec != NULL
- && i_ref < MAX_REFERENCING_UNDEC; i_ref++ )
+ /* Unlink referenced pictures */
+ if( p_mb->p_forw_top != NULL )
{
- *p_undec_p->pp_referencing_undec[i_ref].pp_frame = p_undec_p->p_picture;
- vout_LinkPicture( p_fifo->p_vpar.p_vout, p_picture );
-
- /* Try to put the referencing picture in the video FIFO */
- vpar_DecodePicture( p_fifo, p_undec_p->pp_referencing_undec[i_ref].p_undec );
+ vout_UnlinkPicture( p_fifo->p_vpar.p_vout, p_mb->p_forw_top );
+ }
+ if( p_mb->p_backw_top != NULL )
+ {
+ vout_UnlinkPicture( p_fifo->p_vpar.p_vout, p_mb->p_backw_top );
+ }
+ if( p_mb->p_forw_bot != NULL )
+ {
+ vout_UnlinkPicture( p_fifo->p_vpar.p_vout, p_mb->p_forw_bot );
+ }
+ if( p_mb->p_backw_bot != NULL )
+ {
+ vout_UnlinkPicture( p_fifo->p_vpar.p_vout, p_mb->p_backw_bot );
}
- /* Unlink referenced pictures */
- if( p_undec_p->p_forward_ref != NULL )
+ /* Unlink picture buffer */
+ vlc_mutex_lock( &p_mb->p_picture->lock_deccount );
+ p_mb->p_picture->i_deccount--;
+ if( p_mb->p_picture->i_deccount == 0 )
{
- vout_UnlinkPicture( p_fifo->p_vpar.p_vout, p_undec_p->p_forward_ref );
- if( p_undec_p->p_backward_ref != NULL )
- {
- vout_UnlinkPicture( p_fifo->p_vpar.p_vout, p_undec_p->p_backward_ref );
- }
+ /* Mark the picture to be displayed */
+ vout_DisplayPicture( p_fifo->p_vpar.p_vout, p_mb->p_picture );
+
+ /* Warn Synchro for its records. */
+ vpar_SynchroEnd( p_fifo->p_vpar );
}
-
- /* Mark the picture to be displayed */
- vout_DisplayPicture( p_fifo->p_vpar.p_vout, p_undec_p->p_picture );
+ vlc_mutex_unlock( & p_mb->p_picture->lock_deccount );
- /* Release the undec_picture_t structure */
+ /* Release the macroblock_t structure */
#define P_buffer p_fifo->p_vpar.vbuffer
vlc_mutex_lock( &P_buffer->lock );
-
- P_buffer->pp_undec_free[ ++P_buffer->i_index ] = p_undec_p;
-
+ P_buffer->pp_mb_free[ ++P_buffer->i_index ] = p_mb;
vlc_mutex_unlock( &P_buffer->lock );
#undef P_buffer
- }
}
/*****************************************************************************
- * vpar_DestroyPicture : destroy a picture in case of error
+ * vpar_DestroyMacroblock : destroy a macroblock in case of error
*****************************************************************************/
-void vpar_DestroyPicture( video_fifo_t * p_fifo, undec_picture_t * p_undec_p )
+void vpar_DestroyMacroblock( video_fifo_t * p_fifo, macroblock_t * p_mb )
{
- int i_ref;
-
- /* Destroy referencing pictures */
- for( i_ref = 0; p_undec_p->pp_referencing_undec[i_ref].p_undec != NULL
- && i_ref < MAX_REFERENCING_UNDEC; i_ref++ )
+ /* Unlink referenced pictures */
+ if( p_mb->p_forw_top != NULL )
{
- /* Try to put the referencing picture in the video FIFO */
- vpar_DestroyPicture( p_fifo, p_undec_p->pp_referencing_undec[i_ref].p_undec );
+ vout_UnlinkPicture( p_fifo->p_vpar.p_vout, p_mb->p_forw_top );
}
-
- /* Unlink referenced pictures */
- if( p_undec_p->p_forward_ref != NULL )
+ if( p_mb->p_backw_top != NULL )
{
- vout_UnlinkPicture( p_fifo->p_vpar.p_vout, p_undec_p->p_forward_ref );
- if( p_undec_p->p_backward_ref != NULL )
- {
- vout_UnlinkPicture( p_fifo->p_vpar.p_vout, p_undec_p->p_backward_ref );
- }
+ vout_UnlinkPicture( p_fifo->p_vpar.p_vout, p_mb->p_backw_top );
}
-
- /* Release the picture buffer */
- vout_DestroyPicture( p_fifo->p_vpar.p_vout, p_undec_p->p_picture );
-
- /* Release the undec_picture_t structure */
+ if( p_mb->p_forw_bot != NULL )
+ {
+ vout_UnlinkPicture( p_fifo->p_vpar.p_vout, p_mb->p_forw_bot );
+ }
+ if( p_mb->p_backw_bot != NULL )
+ {
+ vout_UnlinkPicture( p_fifo->p_vpar.p_vout, p_mb->p_backw_bot );
+ }
+
+ /* Release the macroblock_t structure */
#define P_buffer p_fifo->p_vpar.vbuffer
vlc_mutex_lock( &P_buffer->lock );
-
- P_buffer->pp_undec_free[ ++P_buffer->i_index ] = p_undec_p;
-
+ P_buffer->pp_mb_free[ ++P_buffer->i_index ] = p_mb;
vlc_mutex_unlock( &P_buffer->lock );
#undef P_buffer
- }
}
*******************************************************************************/
static int InitThread( vpar_thread_t *p_vpar )
{
+ int i_dummy;
intf_DbgMsg("vpar debug: initializing video parser thread %p\n", p_vpar);
p_vpar->sequence.nonintra_quant.b_allocated = FALSE;
p_vpar->sequence.chroma_intra_quant.b_allocated = FALSE;
p_vpar->sequence.chroma_nonintra_quant.b_allocated = FALSE;
+ p_vpar->sequence.i_frame_number = 0;
/* Initialize other properties */
#ifdef STATS
bzero( p_vpar->p_vdec, MAX_VDEC*sizeof(vdec_thread_t *) );
- /* Spawn a video_decoder thread */
- /* ??? add the possibility to launch multiple vdec threads */
- if( (p_vpar->p_vdec[0] = vdec_CreateThread( p_vpar )) == NULL )
+ /* Spawn video_decoder threads */
+ /* ??? modify the number of vdecs at runtime ? */
+ for( i_dummy = 0; i_dummy < NB_VDEC; i_dummy++ )
{
- return( 1 );
+ if( (p_vpar->p_vdec[i_dummy] = vdec_CreateThread( p_vpar )) == NULL )
+ {
+ return( 1 );
+ }
}
/* Mark thread as running and return */
intf_DbgMsg("vpar debug: InitThread(%p) succeeded\n", p_vpar);
- return( 0 );
+ return( 0 );
}
/*******************************************************************************
vlc_mutex_lock( &p_vpar->fifo.data_lock );
/* ?? trash all trashable PES packets */
- while( !PARSER_FIFO_ISEMPTY(p_vpar->fifo) )
+ while( !DECODER_FIFO_ISEMPTY(p_vpar->fifo) )
{
- input_NetlistFreePES( p_vpar->bit_stream.p_input, PARSER_FIFO_START(p_vpar->fifo) );
- PARSER_FIFO_INCSTART( p_vpar->fifo );
+ input_NetlistFreePES( p_vpar->bit_stream.p_input,
+ DECODER_FIFO_START(p_vpar->fifo) );
+ DECODER_FIFO_INCSTART( p_vpar->fifo );
}
vlc_mutex_unlock( &p_vpar->fifo.data_lock );
/* Sleep a while */
- msleep( VPAR_IDLE_SLEEP );
+ msleep( VPAR_IDLE_SLEEP );
}
}
/* ?? */
/* Destroy vdec threads */
- for( i_dummy = 0; i_dummy < MAX_VDEC; i_dummy++ )
+ for( i_dummy = 0; i_dummy < NB_VDEC; i_dummy++ )
{
if( p_vpar->p_vdec[i_dummy] != NULL )
vdec_DestroyThread( p_vpar->p_vdec[i_dummy] );
--- /dev/null
+/*****************************************************************************
+ * vpar_blocks.c : blocks parsing
+ * (c)1999 VideoLAN
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Preamble
+ *****************************************************************************/
+#include <errno.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/uio.h>
+#include <X11/Xlib.h>
+#include <X11/extensions/XShm.h>
+
+#include "config.h"
+#include "common.h"
+#include "mtime.h"
+#include "vlc_thread.h"
+
+#include "intf_msg.h"
+#include "debug.h" /* ?? temporaire, requis par netlist.h */
+
+#include "input.h"
+#include "input_netlist.h"
+#include "decoder_fifo.h"
+#include "video.h"
+#include "video_output.h"
+#include "video_parser.h"
+
+#include "video_fifo.h"
+#include "video_decoder.h"
+
+/*
+ * Local prototypes
+ */
+static __inline__ void InitMacroblock( vpar_thread_t * p_vpar,
+ macroblock_t * p_mb, int i_mb_address );
+static __inline__ int MacroblockAddressIncrement( vpar_thread_t * p_vpar );
+static __inline__ void MacroblockModes( vpar_thread_t * p_vpar,
+ macroblock_t * p_mb );
+
+typedef (void *) f_decode_block_t( vpar_thread_t *, macroblock_t *, int );
+
+/*****************************************************************************
+ * vpar_ParseMacroblock : Parse the next macroblock
+ *****************************************************************************/
+void vpar_ParseMacroblock( vpar_thread_t * p_vpar, int * pi_mb_address,
+ int i_mb_previous, int i_mb_base )
+{
+ static f_addb_t ppf_addb_intra[2] = {vdec_AddBlock, vdec_CopyBlock};
+
+ int i_mb, i_b, i_mask, i_x, i_y, pi_pos[3], pi_width[3];
+ macroblock_t * p_mb;
+ f_addb_t pf_addb;
+
+ *pi_mb_address += MacroblockAddressIncrement( p_vpar );
+
+ for( i_mb = i_mb_previous; i_mb < *pi_mb_address; i_mb++ )
+ {
+ /* Skipped macroblock (ISO/IEC 13818-2 7.6.6). */
+ static int pi_dc_dct_reinit[4] = {128,256,512,1024};
+ static f_motion_t pf_motion_skipped[4] = {NULL, vdec_MotionField,
+ vdec_MotionField, vdec_MotionFrame};
+
+ /* Reset DC predictors (7.2.1). */
+ p_vpar->slice.pi_dct_pred[0] = p_vpar->slice.pi_dct_pred[1]
+ = p_vpar->slice.pi_dct_pred[2]
+ = pi_dc_dct_reinit[p_vpar->picture.i_intra_dc_precision];
+
+ if( p_vpar->picture.i_coding_type == P_CODING_TYPE )
+ {
+ /* Reset motion vector predictors (ISO/IEC 13818-2 7.6.3.4). */
+ bzero( p_vpar->slice.pppi_pmv, 8*sizeof(int) );
+ }
+
+ if( (p_mb = p_vpar->picture.pp_mb[i_mb_base + i_mb] =
+ vpar_NewMacroblock( &p_vpar->vfifo )) == NULL )
+ {
+ p_vpar->picture.b_error = TRUE;
+ intf_ErrMsg("vpar error: macroblock list is empty !");
+ return;
+ }
+
+ InitMacroblock( p_vpar, p_mb, i_mb );
+
+ /* No IDCT nor AddBlock. */
+ for( i_b = 0; i_b < 12; i_b++ )
+ {
+ p_mb->pf_idct[i_b] = vdec_DummyIDCT;
+ p_mb->pf_addb[i_b] = vdec_DummyBlock;
+ }
+
+ /* Motion type is picture structure. */
+ p_mb->pf_motion = pf_motion_skipped[p_vpar->picture.i_structure];
+
+ /* Predict from field of same parity. */
+ /* ??? */
+ }
+
+ /* Get a macroblock structure. */
+ if( (p_mb = p_vpar->picture.pp_mb[i_mb_base + *pi_mb_address] =
+ vpar_NewMacroblock( &p_vpar->vfifo )) == NULL )
+ {
+ p_vpar->picture.b_error = TRUE;
+ intf_ErrMsg("vpar error: macroblock list is empty !");
+ return;
+ }
+
+ InitMacroblock( p_vpar, p_mb, *pi_mb_address );
+
+ /* Parse off macroblock_modes structure. */
+ MacroblockModes( p_vpar, p_mb );
+
+ if( p_vpar->mb.i_mb_type & MB_QUANT )
+ {
+ LoadQuantizerScale( p_vpar );
+ }
+
+ if( p_vpar->mb.i_mb_type & MB_MOTION_FORWARD )
+ {
+ (*p_vpar->sequence.pf_decode_mv)( p_vpar, 0 );
+ }
+
+ if( p_vpar->mb.i_mb_type & MB_MOTION_BACKWARD )
+ {
+ (*p_vpar->sequence.pf_decode_mv)( p_vpar, 1 );
+ }
+
+ if( p_vpar->picture.b_concealment_mv && (p_vpar->mb.i_mb_type & MB_INTRA) )
+ {
+ DumpBits( &p_vpar->bit_stream, 1 );
+ }
+
+ if( p_vpar->mb.i_mb_type & MB_PATTERN )
+ {
+ (*p_vpar->sequence.pf_decode_pattern)( p_vpar );
+ }
+ else
+ {
+ int pi_coded_block_pattern[2] = {0,
+ (1 << 4+2*p_vpar->sequence.i_chroma_nb_blocks) - 1};
+ p_vpar->mb.i_coded_block_pattern = pi_coded_block_pattern
+ [p_vpar->mb.i_mb_type & MB_INTRA];
+ }
+
+ pf_addb = ppf_addb_intra[p_vpar->mb.i_mb_type & MB_INTRA];
+
+ /* C'est de la merde, il faut recommencer */
+
+ i_x = p_mb->i_mb_x << 4;
+ i_y = p_mb->i_mb_y << 4;
+
+ pi_pos[0] = i_y*(p_vpar->sequence.i_width
+ << (!p_vpar->picture.b_frame_structure))
+ + (p_mb->i_structure == BOTTOM_FIELD)*p_vpar->sequence.i_width
+ + i_x;
+ pi_pos[1] = pi_pos[2] = i_y*(p_vpar->sequence.i_chroma_width
+ << (!p_vpar->picture.b_frame_structure))
+ + (p_mb->i_structure == BOTTOM_FIELD)*p_vpar->sequence.i_chroma_width
+ + (i_x >> (3-p_vpar->sequence.i_chroma_format));
+ pi_width[0] = p_vpar->sequence.i_width << (!p_vpar->picture.b_frame_structure
+ || p_vpar->mb.b_dct_type);
+ pi_width[1] = pi_width[2] = p_vpar->sequence.i_chroma_width
+ << (!p_vpar->picture.b_frame_structure || p_vpar->mb.b_dct_type);
+
+ /* Effectively decode blocks. */
+ for( i_b = 0, i_mask = 1 << (3 + 2*p_vpar->sequence.i_chroma_nb_blocks);
+ i_b < 4 + 2*p_vpar->sequence.i_chroma_nb_blocks; i_b++, i_mask >>= 1 )
+ {
+ if( p_vpar->mb.i_coded_block_pattern & i_mask )
+ {
+ static f_decode_block_t pppf_decode_block[2][2] =
+ { {vpar_DecodeMPEG1Non, vpar_DecodeMPEG1Intra},
+ {vpar_DecodeMPEG2Non, vpar_DecodeMPEG2Intra} };
+ static int pi_x[12] = {0,8,0,8,0,0,0,0,8,8,8,8};
+ static int pi_y[12] = {0,0,8,8,0,0,8,8,0,0,8,8};
+ data_t pi_data[12] =
+ {p_mb->p_picture->p_y, p_mb->p_picture->p_y,
+ p_mb->p_picture->p_y, p_mb->p_picture->p_y,
+ p_mb->p_picture->p_u, p_mb->p_picture->p_v,
+ p_mb->p_picture->p_u, p_mb->p_picture->p_v,
+ p_mb->p_picture->p_u, p_mb->p_picture->p_v,
+ p_mb->p_picture->p_u, p_mb->p_picture->p_v};
+
+ bzero( p_mb->ppi_blocks[i_b], 64*sizeof(elem_t) );
+ (*pppf_decode_block[p_vpar->sequence.b_mpeg2]
+ [p_vpar->mb.i_mb_type & MB_INTRA])
+ ( p_vpar, p_mb, i_b );
+
+ /* decode_block has already set pf_idct and pi_sparse_pos. */
+ p_mb->pf_addb[i_b] = pf_addb;
+
+ /* Calculate block coordinates. */
+ p_mb->p_data[i_b] = pi_data[i_b] + pi_pos[i_b >> 2]
+ + pi_y[i_b]*pi_width[i_b >> 2]
+ + (p_vpar->mb.b_dct_type & ((i_b & 2) >> 1))
+ /* INACHEVÉ parce que trop pourri ! */
+ }
+ else
+ {
+ /* Block not coded, so no IDCT, nor AddBlock */
+ p_mb->pf_addb[i_b] = vdec_DummyBlock;
+ p_mb->pf_idct[i_b] = vdec_DummyIDCT;
+ }
+ }
+
+ if( !( p_vpar->mb.i_mb_type & MB_INTRA ) )
+ {
+ static int pi_dc_dct_reinit[4] = {128,256,512,1024};
+
+ /* Reset DC predictors (7.2.1). */
+ p_vpar->slice.pi_dct_pred[0] = p_vpar->slice.pi_dct_pred[1]
+ = p_vpar->slice.pi_dct_pred[2]
+ = pi_dc_dct_reinit[p_vpar->picture.i_intra_dc_precision];
+ }
+ else if( !p_vpar->picture.b_concealment_mv )
+ {
+ /* Reset MV predictors. */
+ bzero( p_vpar->slice.pppi_pmv, 8*sizeof(int) );
+ }
+
+ if( (p_vpar->picture.i_coding_type == P_CODING_TYPE) &&
+ !(p_vpar->mb.i_mb_type & (MB_MOTION_FORWARD|MB_INTRA)) )
+ {
+ /* Special No-MC macroblock in P pictures (7.6.3.5). */
+ p_vpar->slice.pppi_pmv[0][0][0] = p_vpar->slice.pppi_pmv[0][0][1] =
+ p_vpar->slice.pppi_pmv[1][0][0] = p_vpar->slice.pppi_pmv[1][0][1] = 0;
+
+ /* motion type ?????? */
+ /* predict from field of same parity ????? */
+ }
+}
+
+/*****************************************************************************
+ * InitMacroblock : Initialize macroblock values
+ *****************************************************************************/
+static __inline__ void InitMacroblock( vpar_thread_t * p_vpar,
+ macroblock_t * p_mb, int i_mb_address )
+{
+ p_mb->p_picture = p_vpar->picture.p_picture;
+ p_mb->i_structure = p_vpar->picture.i_structure;
+ p_mb->i_mb_x = i_mb_address % p_vpar->sequence.i_mb_width;
+ p_mb->i_mb_y = i_mb_address / p_vpar->sequence.i_mb_width;
+ p_mb->i_chroma_nb_blocks = p_vpar->sequence.i_chroma_nb_blocks;
+
+ p_mb->i_lum_incr = p_vpar->picture.i_lum_incr;
+ p_mb->i_chroma_incr = p_vpar->picture.i_chroma_incr;
+}
+
+/*****************************************************************************
+ * MacroblockAddressIncrement : Get the macroblock_address_increment field
+ *****************************************************************************/
+static __inline__ int MacroblockAddressIncrement( vpar_thread_t * p_vpar )
+{
+ /* À pomper dans Berkeley */
+}
+
+/*****************************************************************************
+ * MacroblockModes : Get the macroblock_modes structure
+ *****************************************************************************/
+static __inline__ void MacroblockModes( vpar_thread_t * p_vpar,
+ macroblock_t * p_mb )
+{
+ static f_motion_t pf_motion[2][4] =
+ { {NULL, vdec_FieldRecon, vdec_16x8Recon, vdec_DMVRecon},
+ {NULL, vdec_FieldRecon, vdec_FrameRecon, vdec_DMVRecon} };
+ static int ppi_mv_count[2][4] = { {0, 1, 2, 1}, {0, 2, 1, 1} };
+ static int ppi_mv_format[2][4] = { {0, 1, 1, 1}, {0, 1, 2, 1} };
+
+ /* Get macroblock_type. */
+ p_vpar->mb.i_mb_type = (*p_vpar->picture.pf_macroblock_type)
+ ( vpar_thread_t * p_vpar );
+
+ /* SCALABILITY : warning, we don't know if spatial_temporal_weight_code
+ * has to be dropped, take care if you use scalable streams. */
+ /* DumpBits( &p_vpar->bit_stream, 2 ); */
+
+ if( !(p_vpar->mb.i_mb_type & (MB_MOTION_FORWARD |Â MB_MOTION_BACKWARD))
+ || p_vpar->picture.b_frame_pred_frame_dct )
+ {
+ /* If mb_type has neither MOTION_FORWARD nor MOTION_BACKWARD, this
+ * is useless, but also harmless. */
+ p_vpar->mb.i_motion_type = MOTION_FRAME;
+ }
+ else
+ {
+ p_vpar->mb.i_motion_type = GetBits( &p_vpar->bit_stream, 2 );
+ }
+
+ p_mb->f_motion = pf_motion[p_vpar->picture.b_frame_structure]
+ [p_vpar->mb.i_motion_type];
+ p_vpar->mb.i_mv_count = ppi_mv_count[p_vpar->picture.b_frame_structure]
+ [p_vpar->mb.i_motion_type];
+ p_vpar->mb.i_mv_format = ppi_mv_format[p_vpar->picture.b_frame_structure]
+ [p_vpar->mb.i_motion_type];
+
+ if( (p_vpar->picture.i_structure == FRAME_STRUCTURE) &&
+ (!p_vpar->picture.b_frame_pred_frame_dct) &&
+ (p_var->mb.i_mb_type & (MB_PATTERN|MB_INTRA)) )
+ {
+ p_vpar->mb.b_dct_type = GetBits( &p_vpar->bit_stream, 1 );
+ }
+ else
+ {
+ p_vpar->mb.b_dct_type = 0;
+ }
+}
+
+/*****************************************************************************
+ * vpar_IMBType : macroblock_type in I pictures
+ *****************************************************************************/
+int vpar_IMBType( vpar_thread_t * p_vpar )
+{
+ /* À pomper dans Berkeley */
+}
+
+/*****************************************************************************
+ * vpar_PMBType : macroblock_type in P pictures
+ *****************************************************************************/
+int vpar_PMBType( vpar_thread_t * p_vpar )
+{
+ /* À pomper dans Berkeley */
+}
+
+/*****************************************************************************
+ * vpar_BMBType : macroblock_type in B pictures
+ *****************************************************************************/
+int vpar_BMBType( vpar_thread_t * p_vpar )
+{
+ /* À pomper dans Berkeley */
+}
+
+/*****************************************************************************
+ * vpar_DMBType : macroblock_type in D pictures
+ *****************************************************************************/
+int vpar_DMBType( vpar_thread_t * p_vpar )
+{
+ /* À pomper dans Berkeley */
+}
+
+/*****************************************************************************
+ * vpar_CodedPattern420 : coded_block_pattern with 420 chroma
+ *****************************************************************************/
+int vpar_CodedPattern420( vpar_thread_t * p_vpar )
+{
+ /* À pomper dans Berkeley */
+}
+
+/*****************************************************************************
+ * vpar_CodedPattern422 : coded_block_pattern with 422 chroma
+ *****************************************************************************/
+int vpar_CodedPattern422( vpar_thread_t * p_vpar )
+{
+ /* À pomper dans Berkeley + attention ! y'a 2 bits en plus en MPEG2 */
+}
+
+/*****************************************************************************
+ * vpar_CodedPattern444 : coded_block_pattern with 444 chroma
+ *****************************************************************************/
+int vpar_CodedPattern444( vpar_thread_t * p_vpar )
+{
+ /* À pomper dans Berkeley + attention ! y'a 4 bits en plus en MPEG2 */
+}
+
+/*****************************************************************************
+ * vpar_DecodeMPEG1Non : decode MPEG-1 non-intra blocks
+ *****************************************************************************/
+void vpar_DecodeMPEG1Non( vpar_thread_t * p_vpar, macroblock_t * p_mb, int i_b )
+{
+ /* À pomper dans Berkeley. Pour toutes ces fonctions, il faut mettre
+ p_mb->pf_idct[i_b] Ã :
+ - vdec_IDCT ou
+ - vdec_SparseIDCT si la matrice n'a qu'un coefficient non nul.
+ Dans le deuxième cas, p_mb->pi_sparse_pos[i_b] contient le numéro
+ de ce coefficient. */
+
+ if( p_vpar->picture.i_coding_type == D_CODING_TYPE )
+ {
+ /* Remove end_of_macroblock (always 1, prevents startcode emulation)
+ * ISO/IEC 11172-2 section 2.4.2.7 and 2.4.3.6 */
+ DumpBits( &p_vpar->fifo, 1 );
+ }
+}
+
+/*****************************************************************************
+ * vpar_DecodeMPEG1Intra : decode MPEG-1 intra blocks
+ *****************************************************************************/
+void vpar_DecodeMPEG1Intra( vpar_thread_t * p_vpar, macroblock_t * p_mb, int i_b )
+{
+ /* À pomper dans Berkeley. */
+
+ if( p_vpar->picture.i_coding_type == D_CODING_TYPE )
+ {
+ /* Remove end_of_macroblock (always 1, prevents startcode emulation)
+ * ISO/IEC 11172-2 section 2.4.2.7 and 2.4.3.6 */
+ DumpBits( &p_vpar->fifo, 1 );
+ }
+}
+
+/*****************************************************************************
+ * vpar_DecodeMPEG2Non : decode MPEG-2 non-intra blocks
+ *****************************************************************************/
+void vpar_DecodeMPEG2Non( vpar_thread_t * p_vpar, macroblock_t * p_mb, int i_b )
+{
+ /* À pomper dans Berkeley. Bien sûr les matrices seront différentes... */
+}
+
+/*****************************************************************************
+ * vpar_DecodeMPEG2Intra : decode MPEG-2 intra blocks
+ *****************************************************************************/
+void vpar_DecodeMPEG2Intra( vpar_thread_t * p_vpar, macroblock_t * p_mb, int i_b )
+{
+ /* À pomper dans Berkeley. */
+}
* (c)1999 VideoLAN
*****************************************************************************/
-/* ?? passer en terminate/destroy avec les signaux supplémentaires */
-
/*****************************************************************************
* Preamble
*****************************************************************************/
#include "decoder_fifo.h"
#include "video.h"
#include "video_output.h"
+#include "vpar_blocks.h"
#include "video_parser.h"
-#include "undec_picture.h"
+#include "macroblock.h"
#include "video_fifo.h"
#include "video_decoder.h"
/*
* Local prototypes
*/
+static __inline__ void NextStartCode( vpar_thread_t * p_vpar );
+static void GroupHeader( vpar_thread_t * p_vpar )
+static void PictureHeader( vpar_thread_t * p_vpar )
+static void __inline__ ReferenceUpdate( vpar_thread_t * p_vpar,
+ int i_coding_type,
+ picture_t * p_newref )
+static void __inline__ ReferenceReplace( vpar_thread_t * p_vpar,
+ int i_coding_type,
+ picture_t * p_newref )
+static void SliceHeader00( vpar_thread_t * p_vpar,
+ int * pi_mb_address, int i_mb_base,
+ elem_t * p_y, p_u, p_v, u32 i_vert_code )
+static void SliceHeader01( vpar_thread_t * p_vpar,
+ int * pi_mb_address, int i_mb_base,
+ elem_t * p_y, p_u, p_v, u32 i_vert_code )
+static void SliceHeader10( vpar_thread_t * p_vpar,
+ int * pi_mb_address, int i_mb_base,
+ elem_t * p_y, p_u, p_v, u32 i_vert_code )
+static void SliceHeader11( vpar_thread_t * p_vpar,
+ int * pi_mb_address, int i_mb_base,
+ elem_t * p_y, p_u, p_v, u32 i_vert_code )
+static __inline__ void SliceHeader( vpar_thread_t * p_vpar,
+ int * pi_mb_address, int i_mb_base,
+ elem_t * p_y, p_u, p_v, u32 i_vert_code )
+static void ExtensionAndUserData( vpar_thread_t * p_vpar )
/*****************************************************************************
* vpar_NextSequenceHeader : Find the next sequence header
*****************************************************************************/
static __inline__ void NextStartCode( vpar_thread_t * p_vpar )
{
- /* Re-align the buffer to an 8-bit boundary */
+ /* Re-align the buffer on an 8-bit boundary */
DumpBits( &p_vpar->bit_stream, p_vpar->bit_stream.fifo.i_available & 7 );
while( ShowBits( &p_vpar->bit_stream, 24 ) != 0x01L && !p_vpar->b_die )
/*****************************************************************************
* SequenceHeader : Parse the next sequence header
*****************************************************************************/
-#define RESERVED -1
-static double d_frame_rate_table[16] =
-{
- 0.0,
- ((23.0*1000.0)/1001.0),
- 24.0,
- 25.0,
- ((30.0*1000.0)/1001.0),
- 30.0,
- 50.0,
- ((60.0*1000.0)/1001.0),
- 60.0,
-
- RESERVED,
- RESERVED,
- RESERVED,
- RESERVED,
- RESERVED,
- RESERVED,
- RESERVED
-};
-
static void SequenceHeader( vpar_thread_t * p_vpar )
{
+#define RESERVED -1
+ static double d_frame_rate_table[16] =
+ {
+ 0.0,
+ ((23.0*1000.0)/1001.0),
+ 24.0,
+ 25.0,
+ ((30.0*1000.0)/1001.0),
+ 30.0,
+ 50.0,
+ ((60.0*1000.0)/1001.0),
+ 60.0,
+ RESERVED, RESERVED, RESERVED, RESERVED, RESERVED, RESERVED, RESERVED
+ };
+#undef RESERVED
+
int i_height_save, i_width_save;
i_height_save = p_vpar->sequence.i_height;
i_width_save = p_vpar->sequence.i_width;
- p_vpar->sequence.i_height = ntohl( GetBits( p_vpar->bit_stream, 12 ) );
- p_vpar->sequence.i_width = ntohl( GetBits( p_vpar->bit_stream, 12 ) );
+ p_vpar->sequence.i_height = GetBits( p_vpar->bit_stream, 12 );
+ p_vpar->sequence.i_width = GetBits( p_vpar->bit_stream, 12 );
p_vpar->sequence.i_ratio = GetBits( p_vpar->bit_stream, 4 );
p_vpar->sequence.d_frame_rate =
d_frame_rate_table( GetBits( p_vpar->bit_stream, 4 ) );
/*
* Sequence Extension
*/
- if( ShowBits( p_vpar->bit_stream, 32 ) == EXTENSION_START_CODE )
+ NextStartCode( p_vpar );
+ if( ShowBits( &p_vpar->bit_stream, 32 ) == EXTENSION_START_CODE )
{
int i_dummy;
+ static int pi_chroma_nb_blocks[4] = {0, 1, 2, 4};
+ static (void *) ppf_chroma_pattern[4]( vpar_thread_t * ) =
+ {NULL, vpar_CodedPattern420,
+ vpar_CodedPattern422, vpar_CodedPattern444};
/* Parse sequence_extension */
DumpBits32( &p_vpar->bit_stream );
DumpBits( &p_vpar->bit_stream, 12 );
p_vpar->sequence.b_progressive = GetBits( &p_vpar->bit_stream, 1 );
p_vpar->sequence.i_chroma_format = GetBits( &p_vpar->bit_stream, 2 );
+ p_vpar->sequence.i_chroma_width = p_vpar->sequence.i_width
+ >> (3-p_vpar->sequence.i_chroma_format);
+ p_vpar->sequence.i_chroma_nb_blocks = pi_chroma_nb_blocks
+ [p_vpar->sequence.i_chroma_format];
+ p_vpar->sequence.pf_decode_pattern = ppf_chroma_pattern
+ [p_vpar->sequence.i_chroma_format];
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 */
p_vpar->sequence.d_frame_rate *= (i_dummy + 1)
/ (GetBits( &p_vpar->bit_stream, 5 ) + 1);
- /* Extension and User data */
- ExtensionAndUserData( p_vpar );
+ p_vpar->sequence.pf_decode_mv = vpar_MPEG2MotionVector;
}
else
{
/* It's an MPEG-1 stream. Put adequate parameters. */
p_vpar->sequence.b_progressive = 1;
- p_vpar->i_chroma_format = CHROMA_420;
+ p_vpar->sequence.i_chroma_format = CHROMA_420;
+ p_vpar->sequence.i_chroma_width = p_vpar->sequence.i->width >> 2;
+ p_vpar->sequence.i_chroma_nb_blocks = 2;
+ p_vpar->sequence.pf_decode_pattern = vpar_CodedPattern420;
+
+ p_vpar->sequence.pf_decode_mv = vpar_MPEG1MotionVector;
}
p_vpar->sequence.i_mb_width = (p_vpar->sequence.i_width + 15) / 16;
p_vpar->sequence.i_mb_height = (p_vpar->sequence.b_progressive) ?
(p_vpar->sequence.i_height + 15) / 16 :
2 * (p_vpar->sequence.i_height + 31) / 32;
+ p_vpar->sequence.i_mb_size = p_vpar->sequence.i_mb_width
+ * p_vpar->sequence.i_mb_height;
p_vpar->sequence.i_width = (p_vpar->sequence.i_mb_width * 16);
p_vpar->sequence.i_height = (p_vpar->sequence.i_mb_height * 16);
+ p_vpar->sequence.i_size = p_vpar->sequence.i_width
+ * p_vpar->sequence.i_height;
- if( p_vpar->sequence.i_width != i_width_save
- || p_vpar->sequence.i_height != i_height_save
- || p_vpar->sequence.p_frame_lum_lookup == NULL )
+ /* Slice Header functions */
+ if( p_vpar->sequence.i_height <= 2800 )
{
- int i_x, i_y;
- pel_lookup_table * p_fr, p_fl;
- int i_fr, i_fl;
- static int pi_chroma_size[4] = {0, 2, 1, 0}
-#define Sequence p_vpar->sequence
-
- /* The size of the pictures has changed. Probably a new sequence.
- * We must recalculate the lookup matrices. */
-
- /* First unlink the previous lookup matrices so that they can
- * be freed in the future. */
- if( Sequence.p_frame_lum_lookup != NULL )
+ if( p_vpar->sequence.i_scalable_mode != SC_DP )
{
- UNLINK_LOOKUP( Sequence.p_frame_lum_lookup );
- UNLINK_LOOKUP( Sequence.p_field_lum_lookup );
- UNLINK_LOOKUP( Sequence.p_frame_chroma_lookup );
- UNLINK_LOOKUP( Sequence.p_field_chroma_lookup );
+ p_vpar->sequence.pf_slice_header = SliceHeader00;
}
-
- /* Allocate the new lookup tables. */
- Sequence.p_frame_lum_lookup
- = (pel_lookup_table_t *)malloc( sizeof( pel_lookup_table_t ) *
- Sequence.i_width * Sequence.i_height );
- Sequence.p_field_lum_lookup
- = (pel_lookup_table_t *)malloc( sizeof( pel_lookup_table_t ) *
- Sequence.i_width * Sequence.i_height );
- Sequence.p_frame_chroma_lookup
- = (pel_lookup_table_t *)malloc( sizeof( pel_lookup_table_t ) *
- Sequence.i_width * Sequence.i_height
- >> pi_chroma_size[Sequence.i_chroma_format] );
- Sequence.p_field_chroma_lookup
- = (pel_lookup_table_t *)malloc( sizeof( pel_lookup_table_t ) *
- Sequence.i_width * Sequence.i_height
- >> pi_chroma_size[Sequence.i_chroma_format] );
-
- if( !Sequence.p_frame_lum_lookup ||Â !Sequence.p_field_lum_lookup
- || !Sequence.p_frame_chroma_lookup
- ||Â !Sequence.p_field_chroma_lookup )
+ else
{
- intf_DbgMsg("vpar error: not enough memory for lookup tables");
- p_vpar->b_error = 1;
- return;
+ p_vpar->sequence.pf_slice_header = SliceHeader01;
}
-
- /* Fill in the luminance lookup tables */
- p_fr = &Sequence.p_frame_lum_lookup->pi_pel;
- p_fl = &Sequence.p_field_lum_lookup->pi_pel;
- i_fr = i_fl = 0;
-
- for( i_y = 0; i_y < Sequence.i_height; i_y++ )
+ }
+ else
+ {
+ if( p_vpar->sequence.i_scalable_mode != SC_DP )
{
- int i_mb_y, i_b_y, i_pos_y;
- i_mb_y = i_y >> 4;
- i_b_y = (i_y & 15) >> 3;
- i_pos_y = (i_y & 7);
-
- for( i_x = 0; i_x < Sequence.i_width; i_x++ )
- {
- int i_mb_x, i_b_x, i_pos_x;
- i_mb_x = i_x >> 4;
- i_b_x = (i_x & 15) >> 3;
- i_pos_x = (i_x & 7);
-
- p_fl[i_fr + i_x] = p_fr[i_fr + i_x]
- = (i_mb_y*Sequence.i_mb_width + i_mb_y)*256
- + ((i_b_y << 1) + i_b_x)*64
- + i_pos_y*8 + i_pos_x;
- }
- i_fr += Sequence.i_width;
- i_fl += Sequence.i_width << 1;
- if( i_fl == Sequence.i_width*Sequence.i_height )
- {
- i_fl = Sequence.i_width;
- }
+ p_vpar->sequence.pf_slice_header = SliceHeader10;
}
-
- /* Fill in the chrominance lookup tables */
- p_fr = &Sequence.p_frame_chroma_lookup->pi_pel;
- p_fl = &Sequence.p_field_chroma_lookup->pi_pel;
- i_fr = i_fl = 0;
-
- switch( p_vpar->i_chroma_format )
+ else
{
- case CHROMA_444:
- /* That's the same as luminance */
- memcopy( &Sequence.p_frame_croma_lookup->pi_pel,
- &Sequence.p_frame_lum_lookup->pi_pel,
- sizeof(PEL_P)*Sequence.i_height*Sequence.i_width );
- memcopy( &Sequence.p_field_croma_lookup->pi_pel,
- &Sequence.p_field_lum_lookup->pi_pel,
- sizeof(PEL_P)*Sequence.i_height*Sequence.i_width );
-
- case CHROMA_422:
- for( i_y = 0; i_y < Sequence.i_height; i_y++ )
- {
- int i_mb_y, i_b_y, i_pos_y;
- i_mb_y = i_y >> 4;
- i_b_y = (i_y & 15) >> 3;
- i_pos_y = (i_y & 7);
-
- for( i_x = 0; i_x < (Sequence.i_width >> 1); i_x++ )
- {
- int i_mb_x, i_pos_x;
- i_mb_x = i_x >> 3;
- i_pos_x = (i_x & 7);
-
- p_fl[i_fr + i_x] = p_fr[i_fr + i_x]
- = (i_mb_y*Sequence.i_mb_width + i_mb_y)*128
- + i_b_y*64
- + i_pos_y*8 + i_pos_x;
- }
- i_fr += Sequence.i_width >> 1;
- i_fl += Sequence.i_width;
- if( i_fl == (Sequence.i_width*Sequence.i_height >> 1) )
- {
- i_fl = (Sequence.i_width >> 1);
- }
- }
+ p_vpar->sequence.pf_slice_header = SliceHeader11;
+ }
+ }
+
+ if( p_vpar->sequence.i_width != i_width_save
+ || p_vpar->sequence.i_height != i_height_save
+ || p_vpar->sequence.p_frame_lum_lookup == NULL )
+ {
- case CHROMA_420:
- for( i_y = 0; i_y < (Sequence.i_height >> 1); i_y++ )
- {
- int i_mb_y, i_pos_y;
- i_mb_y = i_y >> 3;
- i_pos_y = (i_y & 7);
-
- for( i_x = 0; i_x < (Sequence.i_width >> 1); i_x++ )
- {
- int i_mb_x, i_pos_x;
- i_mb_x = i_x >> 3;
- i_pos_x = (i_x & 7);
-
- p_fl[i_fr + i_x] = p_fr[i_fr + i_x]
- = (i_mb_y*Sequence.i_mb_width + i_mb_y)*64
- + i_pos_y*8 + i_pos_x;
- }
- i_fr += Sequence.i_width >> 1;
- i_fl += Sequence.i_width;
- if( i_fl == (Sequence.i_width*Sequence.i_height >> 2) )
- {
- i_fl = Sequence.i_width >> 1;
- }
- }
- } /* switch */
-
- /* Link the new lookup tables so that they don't get freed all
- * the time. */
- LINK_LOOKUP( Sequence.p_frame_lum_lookup );
- LINK_LOOKUP( Sequence.p_field_lum_lookup );
- LINK_LOOKUP( Sequence.p_frame_chroma_lookup );
- LINK_LOOKUP( Sequence.p_field_chroma_lookup );
-#undef Sequence
}
+
+ /* Extension and User data */
+ ExtensionAndUserData( p_vpar );
}
/*****************************************************************************
*****************************************************************************/
static void PictureHeader( vpar_thread_t * p_vpar )
{
- int i_coding_type;
- mtime_t i_pts;
- undec_picture_t * p_undec_p;
+ static (int *) ppf_macroblock_type[4] = {vpar_IMBType, vpar_PMBType,
+ vpar_BMBType, vpar_DMBType};
+
+ int i_structure;
+ int i_mb_address, i_mb_base, i_mb;
+ elem_t * p_y, p_u, p_v;
+ boolean_t b_parsable;
+ u32 i_dummy;
DumpBits( &p_vpar->bit_stream, 10 ); /* temporal_reference */
- i_coding_type = GetBits( &p_vpar->bit_stream, 3 );
+ p_vpar->picture.i_coding_type = GetBits( &p_vpar->bit_stream, 3 );
+ p_vpar->picture.pf_macroblock_type = ppf_macroblock_type
+ [p_vpar->picture.i_coding_type];
+
+ DumpBits( &p_vpar->bit_stream, 16 ); /* vbv_delay */
- if( ((i_coding_type == P_CODING_TYPE) &&
- (p_vpar->sequence.p_forward == NULL)) ||
- ((i_coding_type == B_CODING_TYPE) &&
- (p_vpar->sequence.p_forward == NULL ||
- p_vpar->sequence.p_backward == NULL)) )
- {
- /* The picture cannot be decoded because we lack one of the
- * reference frames */
+ p_vpar->picture.b_full_pel_forward_vector = GetBits( &p_vpar->bit_stream, 1 );
+ p_vpar->picture.i_forward_f_code = GetBits( &p_vpar->bit_stream, 3 );
+ p_vpar->picture.b_full_pel_backward_vector = GetBits( &p_vpar->bit_stream, 1 );
+ p_vpar->picture.i_backward_f_code = GetBits( &p_vpar->bit_stream, 3 );
+
+ /* extra_information_picture */
+ while( GetBits( &p_vpar->bit_stream, 1 ) )
+ {
+ DumpBits( &p_vpar->bit_stream, 8 );
+ }
+
+ /*
+ * Picture Coding Extension
+ */
+ NextStartCode( p_vpar );
+ if( ShowBits( &p_vpar->bit_stream, 32 ) == EXTENSION_START_CODE )
+ {
+ /* Parse picture_coding_extension */
+ DumpBits32( &p_vpar->bit_stream );
+ /* extension_start_code_identifier */
+ DumpBits( &p_vpar->bit_stream, 4 );
- /* Update the reference pointers */
- ReferenceUpdate( p_vpar, i_coding_type, NULL );
+ p_vpar->picture.ppi_f_code[0][0] = GetBits( &p_vpar->bit_stream, 4 );
+ p_vpar->picture.ppi_f_code[0][1] = GetBits( &p_vpar->bit_stream, 4 );
+ p_vpar->picture.ppi_f_code[1][0] = GetBits( &p_vpar->bit_stream, 4 );
+ p_vpar->picture.ppi_f_code[1][1] = GetBits( &p_vpar->bit_stream, 4 );
+ p_vpar->picture.i_intra_dc_precision = GetBits( &p_vpar->bit_stream, 2 );
+ i_structure = GetBits( &p_vpar->bit_stream, 2 );
+ p_vpar->picture.b_top_field_first = GetBits( &p_vpar->bit_stream, 1 );
+ p_vpar->picture.b_frame_pred_frame_dct
+ = GetBits( &p_vpar->bit_stream, 1 );
+ p_vpar->picture.b_concealment_mv = GetBits( &p_vpar->bit_stream, 1 );
+ p_vpar->picture.b_q_scale_type = GetBits( &p_vpar->bit_stream, 1 );
+ 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 );
+ /* repeat_first_field (ISO/IEC 13818-2 6.3.10 is cryptic and
+ * apparently the reference decoder doesn't use it, so trash it),
+ * chroma_420_type (obsolete) */
+ DumpBits( &p_vpar->bit_stream, 2 );
+ p_vpar->picture.b_progressive_frame = GetBits( &p_vpar->bit_stream, 1 );
- /* Warn Synchro we have trashed a picture */
- vpar_SynchroTrash( p_vpar, i_coding_type );
-
- return;
+ /* composite_display_flag */
+ if( GetBits( &p_vpar->bit_stream, 1 ) )
+ {
+ /* v_axis, field_sequence, sub_carrier, burst_amplitude,
+ * sub_carrier_phase */
+ DumpBits( &p_vpar->bit_stream, 20 );
+ }
+ }
+ else
+ {
+ /* MPEG-1 compatibility flags */
+ p_vpar->i_intra_dc_precision = 0; /* 8 bits */
+ i_structure = FRAME_STRUCTURE;
+ p_vpar->b_frame_pred_frame_dct = TRUE;
+ 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 */
+ b_repeat_first_field = FALSE;
+ p_vpar->picture.b_progressive_frame = TRUE;
}
- if( !(i_pts = vpar_SynchroChoose( p_vpar, i_coding_type )) )
+ if( p_vpar->picture.i_current_structure &&
+ (i_structure == FRAME_STRUCTURE ||
+ i_structure == p_vpar->picture.i_current_structure) )
{
- /* Synchro has decided not to decode the picture */
+ /* We don't have the second field of the buffered frame. */
+ if( p_pvar->picture.p_picture != NULL )
+ {
+ ReferenceReplace( p_vpar,
+ p_vpar->picture.p_second_field_buffer->i_coding_type,
+ NULL );
+
+ for( i_mb = 0; i_mb < p_vpar->sequence.i_mb_size >> 1; i_mb++ )
+ {
+ vpar_DestroyMacroblock( &p_vpar->vfifo,
+ p_vpar->picture.pp_mb[i_mb] );
+ }
+ vout_DestroyPicture( p_vpar->p_vout, p_vpar->picture.p_picture );
+ }
- /* Update the reference pointers */
+ p_pvar->picture.i_current_structure = 0;
+
+ intf_DbgMsg("vpar debug: odd number of field picture.");
+ }
+
+ if( p_vpar->picture.i_current_structure )
+ {
+ /* Second field of a frame. We will decode it if, and only if we
+ * have decoded the first frame. */
+ b_parsable = (p_vpar->picture.p_second_field_buffer != NULL);
+ }
+ else
+ {
+ /* Do we have the reference pictures ? */
+ b_parsable = !((i_coding_type == P_CODING_TYPE) &&
+ (p_vpar->sequence.p_forward == NULL)) ||
+ ((i_coding_type == B_CODING_TYPE) &&
+ (p_vpar->sequence.p_forward == NULL ||
+ p_vpar->sequence.p_backward == NULL));
+
+ /* Does synchro say we have enough time to decode it ? */
+ b_parsable &&= vpar_SynchroChoose( p_vpar, i_coding_type, i_structure );
+ }
+
+ if( !b_parsable )
+ {
+ /* Update the reference pointers. */
ReferenceUpdate( p_vpar, i_coding_type, NULL );
+ /* Warn Synchro we have trashed a picture. */
+ vpar_SynchroTrash( p_vpar, i_coding_type, i_structure );
+
+ /* Update context. */
+ if( i_structure != FRAME_STRUCTURE )
+ p_vpar->picture.i_current_structure = i_structure;
+ p_vpar->picture.p_picture = NULL;
+
return;
}
- /* OK, now we are sure we will decode the picture. Get a structure. */
- p_undec_p = vpar_NewPicture( &p_vpar->vfifo );
-
- /* Request a buffer from the video_output. */
- p_undec_p->p_picture = vout_CreatePicture( p_vpar->p_vout,
- SPLITTED_YUV_PICTURE,
- p_vpar->sequence.i_width,
- p_vpar->sequence.i_height,
- p_vpar->sequence.i_chroma_format );
-
- /* Initialize values */
- p_undec_p->i_coding_type = i_conding_type;
- p_undec_p->b_mpeg2 = p_vpar->sequence.b_mpeg2;
- p_undec_p->i_mb_height = p_vpar->sequence.i_mb_height;
- p_undec_p->i_mb_width = p_vpar->sequence.i_mb_width;
- p_undec_p->i_pts = i_pts;
+ /* OK, now we are sure we will decode the picture. */
+#define P_picture p_vpar->picture.p_picture
+ p_vpar->picture.b_error = FALSE;
+
+ if( !p_vpar->picture.i_current_structure )
+ {
+ /* This is a new frame. Get a structure from the video_output. */
+ P_picture = vout_CreatePicture( p_vpar->p_vout,
+ SPLITTED_YUV_PICTURE,
+ p_vpar->sequence.i_width,
+ p_vpar->sequence.i_height,
+ p_vpar->sequence.i_chroma_format );
+
+ /* Initialize values. */
+ P_picture->date = vpar_SynchroDecode( p_vpar, i_coding_type,
+ i_structure );
+ bzero( p_vpar->picture.pp_mb, MAX_MB*sizeof( macroblock_t * ) );
+ p_vpar->picture.i_lum_incr = - 8 + ( p_vpar->sequence.i_width
+ << ( i_structure != FRAME_STRUCTURE ) );
+ p_vpar->picture.i_chroma_incr = -8 + ( p_vpar->sequence.i_width
+ << (( i_structure != FRAME_STRUCTURE ) +
+ ( 3 - p_vpar->sequence.i_chroma_format )) );
+
+ /* Update the reference pointers. */
+ ReferenceUpdate( p_vpar, i_coding_type, p_undec_p );
+ }
+ p_vpar->picture.i_current_structure |= i_structure;
+ p_vpar->picture.i_structure = i_structure;
+ p_vpar->picture.b_frame_structure = (i_structure == FRAME_STRUCTURE);
+
+ /* Initialize picture data for decoding. */
+ if( i_structure == BOTTOM_FIELD )
+ {
+ i_mb_base = p_vpar->sequence.i_mb_size >> 1;
+ }
+ else
+ {
+ i_mb_base = 0;
+ }
+ i_mb_address = 0;
+
+ /* Extension and User data. */
+ ExtensionAndUserData( p_vpar );
+
+ /* Picture data (ISO/IEC 13818-2 6.2.3.7). */
+ NextStartCode( p_vpar );
+ while( i_mb_address+i_mb_base < p_vpar->sequence.i_mb_size
+ && !p_vpar->picture.b_error)
+ {
+ if( ((i_dummy = ShowBits( &p_vpar->bit_stream, 32 ))
+ < SLICE_START_CODE_MIN) ||
+ (i_dummy > SLICE_START_CODE_MAX) )
+ {
+ intf_DbgMsg("vpar debug: premature end of picture");
+ p_vpar->picture.b_error = TRUE;
+ break;
+ }
+ DumpBits32( &p_vpar->bit_stream );
+
+ /* Decode slice data. */
+ SliceHeader( p_vpar, &i_mb_address, i_mb_base, i_dummy & 255 );
+ }
+
+ if( p_vpar->picture.b_error )
+ {
+ /* Trash picture. */
+ for( i_mb = 0; p_vpar->picture.pp_mb[i_mb]; i_mb++ )
+ {
+ vpar_DestroyMacroblock( &p_vpar->vfifo, p_vpar->picture.pp_mb[i_mb] );
+ }
+
+ ReferenceReplace( p_vpar, p_vpar->picture.i_coding_type, NULL );
+ vout_DestroyPicture( p_vpar->p_vout, P_picture );
+
+ /* Prepare context for the next picture. */
+ P_picture = NULL:
+ }
+ else if( p_vpar->picture.i_current_structure == FRAME_STRUCTURE )
+ {
+ /* Frame completely parsed. */
+ for( i_mb = 0; i_mb < p_vpar->sequence.i_mb_size; i_mb++ )
+ {
+ vpar_DecodeMacroblock( &p_vpar->vfifo, p_vpar->picture.pp_mb[i_mb] );
+ }
+
+ /* Prepare context for the next picture. */
+ P_picture = NULL;
+ }
+#undef P_picture
}
/*****************************************************************************
{
if( i_coding_type != B_CODING_TYPE )
{
- /* The P picture would have become the new p_backward reference. */
- vout_UnlinkPicture( p_vpar->p_vout, p_vpar->sequence.p_forward );
+ if( p_vpar->sequence.p_forward != NULL )
+ vout_UnlinkPicture( p_vpar->p_vout, p_vpar->sequence.p_forward );
p_vpar->sequence.p_forward = p_vpar->sequence.p_backward;
p_vpar->sequence.p_backward = p_newref;
+ if( p_newref != NULL )
+ vout_LinkPicture( p_vpar->p_vout, p_newref );
+ }
+}
+
+/*****************************************************************************
+ * ReferenceReplace : Replace the last reference pointer when we destroy
+ * a picture
+ *****************************************************************************/
+static void __inline__ ReferenceReplace( vpar_thread_t * p_vpar,
+ int i_coding_type,
+ picture_t * p_newref )
+{
+ if( i_coding_type != B_CODING_TYPE )
+ {
+ if( p_vpar->sequence.p_backward != NULL )
+ vout_UnlinkPicture( p_vpar->p_vout, p_vpar->sequence.p_backward );
+ p_vpar->sequence.p_backward = p_newref;
+ if( p_newref != NULL )
+ vout_LinkPicture( p_vpar->p_vout, p_newref );
+ }
+}
+
+/*****************************************************************************
+ * SliceHeaderXY : Parse the next slice structure
+ *****************************************************************************
+ * X = i_height > 2800 ?
+ * Y = scalable_mode == SC_DP ?
+ *****************************************************************************/
+static void SliceHeader00( vpar_thread_t * p_vpar,
+ int * pi_mb_address, int i_mb_base,
+ u32 i_vert_code )
+{
+ SliceHeader( p_vpar, pi_mb_address, i_mb_base, i_vert_code );
+}
+
+static void SliceHeader01( vpar_thread_t * p_vpar,
+ int * pi_mb_address, int i_mb_base,
+ u32 i_vert_code )
+{
+ DumpBits( &p_vpar->bit_stream, 7 ); /* priority_breakpoint */
+ SliceHeader( p_vpar, pi_mb_address, i_mb_base, i_vert_code );
+}
+
+static void SliceHeader10( vpar_thread_t * p_vpar,
+ int * pi_mb_address, int i_mb_base,
+ u32 i_vert_code )
+{
+ i_vert_code += GetBits( &p_vpar->bit_stream, 3 ) << 7;
+ SliceHeader( p_vpar, pi_mb_address, i_mb_base, i_vert_code );
+}
+
+static void SliceHeader11( vpar_thread_t * p_vpar,
+ int * pi_mb_address, int i_mb_base,
+ u32 i_vert_code )
+{
+ i_vert_code += GetBits( &p_vpar->bit_stream, 3 ) << 7;
+ DumpBits( &p_vpar->bit_stream, 7 ); /* priority_breakpoint */
+ SliceHeader( p_vpar, pi_mb_address, i_mb_base, i_vert_code );
+}
+
+/*****************************************************************************
+ * SliceHeader : Parse the next slice structure
+ *****************************************************************************/
+static __inline__ void SliceHeader( vpar_thread_t * p_vpar,
+ int * pi_mb_address, int i_mb_base,
+ u32 i_vert_code )
+{
+ /* DC predictors initialization table */
+ static int pi_dc_dct_reinit[4] = {128,256,512,1024};
+
+ int i_mb_address_save = *pi_mb_address;
+
+ /* slice_vertical_position_extension and priority_breakpoint already done */
+ LoadQuantizerScale( p_vpar );
+
+ if( GetBits( &p_vpar->bit_stream, 1 ) )
+ {
+ /* intra_slice, slice_id */
+ DumpBits( &p_vpar->bit_stream, 8 );
+ /* extra_information_slice */
+ while( GetBits( &p_vpar->bit_stream, 1 ) )
+ {
+ DumpBits( &p_vpar->bit_stream, 8 );
+ }
+ }
+
+ *pi_mb_address = (i_vert_code - 1)*p_vpar->sequence.i_mb_width;
+
+ /* Reset DC coefficients predictors (ISO/IEC 13818-2 7.2.1). Why
+ * does the reference decoder put 0 instead of the normative values ? */
+ p_vpar->slice.pi_dct_pred[0] = p_vpar->slice.pi_dct_pred[1]
+ = p_vpar->slice.pi_dct_pred[2]
+ = pi_dc_dct_reinit[p_vpar->picture.i_intra_dc_precision];
+
+ /* Reset motion vector predictors (ISO/IEC 13818-2 7.6.3.4). */
+ bzero( p_vpar->slice.pppi_pmv, 8*sizeof(int) );
+
+ do
+ {
+ vpar_ParseMacroblock( p_vpar, pi_mb_address, i_mb_address_save,
+ i_mb_base );
+ i_mb_address_save = *pi_mb_address;
}
+ while( !ShowBits( &p_vpar->bit_stream, 23 ) );
}
/*****************************************************************************
p_matrix->pi_matrix = pi_array;
}
-
--- /dev/null
+/*****************************************************************************
+ * vpar_motion.c : motion vectors parsing
+ * (c)1999 VideoLAN
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Preamble
+ *****************************************************************************/
+#include <errno.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/uio.h>
+#include <X11/Xlib.h>
+#include <X11/extensions/XShm.h>
+
+#include "config.h"
+#include "common.h"
+#include "mtime.h"
+#include "vlc_thread.h"
+
+#include "intf_msg.h"
+#include "debug.h" /* ?? temporaire, requis par netlist.h */
+
+#include "input.h"
+#include "input_netlist.h"
+#include "decoder_fifo.h"
+#include "video.h"
+#include "video_output.h"
+#include "video_parser.h"
+
+#include "video_fifo.h"
+#include "video_decoder.h"
+
+/*
+ * Local prototypes
+ */
+
+/*****************************************************************************
+ * vpar_MPEG1MotionVector : Parse the next MPEG-1 motion vector
+ *****************************************************************************/
+void vpar_MPEG1MotionVector( vpar_thread_t * p_vpar, int i_mv )
+{
+
+}
+
+/*****************************************************************************
+ * vpar_MPEG2MotionVector : Parse the next MPEG-2 motion vector
+ *****************************************************************************/
+void vpar_MPEG2MotionVector( vpar_thread_t * p_vpar, int i_mv )
+{
+
+}