audio_output_obj = audio_output/audio_output.o \
audio_output/audio_dsp.o
-video_output_obj = video_output/video_output.o \
- video_output/video_x11.o \
- video_output/video_graphics.o
+#video_output_obj = video_output/video_output.o \
+# video_output/video_x11.o \
+# video_output/video_graphics.o
audio_decoder_obj = audio_decoder/audio_decoder.o \
audio_decoder/audio_math.o
video_decoder_ref/recon.o \
video_decoder_ref/spatscal.o
+#video_parser_obj = video_parser/video_parser.o \
+# video_parser/vpar_headers.o \
+# video_parser/vpar_blocks.o \
+# video_parser/vpar_motion.o \
+# video_parser/vpar_synchro.o \
+# video_parser/video_fifo.o
+
+#video_decoder_obj = video_decoder/video_decoder.o \
+# video_decoder/vdec_idct.o \
+# video_decoder/vdec_motion.o
+
misc_obj = misc/mtime.o \
misc/xutils.o \
misc/rsc_files.o \
$(video_output_obj) \
$(audio_decoder_obj) \
$(generic_decoder_obj) \
+ $(video_parser_obj) \
$(video_decoder_obj) \
$(vlan_obj) \
$(misc_obj) \
//#define DVB_EXTENSIONS
//#define DVB_RESTRICTIONS
+/* Define to disable some obscure heuristics behind the video_parser and the
+ * video_decoder that improve performance but are not fully MPEG2 compliant
+ * and might cause problems with some very weird streams. */
+//#define MPEG2_COMPLIANT
+
/* Define for profiling support */
//#define STATS
/* ?? this constant will probably evolve to a calculated value */
#define VOUT_DISPLAY_TOLERANCE 150000
+/*******************************************************************************
+ * Video parser configuration
+ *******************************************************************************/
+
+#define VPAR_IDLE_SLEEP 100000
+
+/* Number of macroblock buffers available. It should be always greater than
+ * twice the number of macroblocks in a picture. VFIFO_SIZE + 1 should also
+ * be a power of two. */
+#define VFIFO_SIZE 4095
+
+/* Maximum number of macroblocks in a picture. */
+#define MAX_MB 2048
+
/*******************************************************************************
* Video decoder configuration
*******************************************************************************/
#define VDEC_IDLE_SLEEP 100000
+/* Number of video_decoder threads to launch on startup of the video_parser.
+ * It should always be less than half the number of macroblocks of a
+ * picture. */
+#define NB_VDEC 1
+
/*******************************************************************************
* Generic decoder configuration
*******************************************************************************/
*****************************************************************************/
static __inline__ byte_t GetByte( bit_stream_t * p_bit_stream )
{
- /* Is the input thread dying ? */
- if ( p_bit_stream->p_input->b_die )
- {
- return( 0 );
- }
-
/* Are there some bytes left in the current TS packet ? */
if ( p_bit_stream->i_byte < p_bit_stream->p_ts->i_payload_end )
{
* time to jump to the next PES packet */
if ( p_bit_stream->p_ts->p_next_ts == NULL )
{
+ /* Is the input thread dying ? */
+ if ( p_bit_stream->p_input->b_die )
+ {
+ return( 0 );
+ }
+
/* We are going to read/write the start and end indexes of the
* decoder fifo and to use the fifo's conditional variable,
* that's why we need to take the lock before */
/******************************************************************************
* NeedBits : reads i_bits new bits in the bit stream and stores them in the
- * bit buffer
+ * <F4> bit buffer
******************************************************************************
* - i_bits must be less or equal 32 !
* - There is something important to notice with that function : if the number
p_bit_stream->fifo.buffer <<= i_bits;
p_bit_stream->fifo.i_available -= i_bits;
}
+
+/******************************************************************************
+ * DumpBits32 : removes 32 bits from the bit buffer
+ ******************************************************************************
+ * This function actually believes that you have already put 32 bits in the
+ * bit buffer, so you can't you use it anytime.
+ ******************************************************************************/
+static __inline__ void DumpBits32( bit_stream_t * p_bit_stream )
+{
+ p_bit_stream->fifo.buffer = 0;
+ p_bit_stream->fifo.i_available = 0;
+}
+
+/*
+ * For the following functions, please read VERY CAREFULLY the warning in
+ * NeedBits(). If i_bits > 24, the stream parser must be already aligned
+ * on an 8-bit boundary, or you will get curious results (that is, you
+ * need to call RealignBits() before).
+ */
+
+/******************************************************************************
+ * ShowBits : return i_bits bits from the bit stream
+ ******************************************************************************/
+static __inline__ u32 ShowBits( bit_stream_t * p_bit_stream, int i_bits )
+{
+ NeedBits( p_bit_stream, i_bits );
+ return( p_bit_stream->fifo.buffer >> (32 - i_bits) );
+}
+
+/******************************************************************************
+ * GetBits : returns i_bits bits from the bit stream and removes them
+ ******************************************************************************/
+static __inline__ u32 GetBits( bit_stream_t * p_bit_stream, int i_bits )
+{
+ u32 i_buffer;
+
+ NeedBits( p_bit_stream, i_bits );
+ i_buffer = p_bit_stream->fifo.buffer >> (32 - i_bits);
+ DumpBits( p_bit_stream, i_bits );
+ return( i_buffer );
+}
+
+/******************************************************************************
+ * GetBits32 : returns 32 bits from the bit stream and removes them
+ ******************************************************************************/
+static __inline__ u32 GetBits32( bit_stream_t * p_bit_stream )
+{
+ u32 i_buffer;
+
+ NeedBits( p_bit_stream, 32 );
+ i_buffer = p_bit_stream->fifo.buffer;
+ DumpBits32( p_bit_stream );
+ return( i_buffer );
+}
+
+/******************************************************************************
+ * RealignBits : realigns the bit buffer on an 8-bit boundary
+ ******************************************************************************/
+static __inline__ void RealignBits( bit_stream_t * p_bit_stream )
+{
+ DumpBits( p_bit_stream, p_bit_stream->fifo.i_available & 7 );
+}
--- /dev/null
+/*****************************************************************************
+ * vdec_idct.h : types for the inverse discrete cosine transform
+ * (c)1999 VideoLAN
+ *****************************************************************************
+ *****************************************************************************
+ * Requires:
+ * "config.h"
+ * "common.h"
+ * "vlc_thread.h"
+ * "video_parser.h"
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Common declarations
+ *****************************************************************************/
+#define elem_t short
+
+/*****************************************************************************
+ * Function pointers
+ *****************************************************************************/
+typedef void (*f_idct_t)( elem_t*, int );
+
+/*****************************************************************************
+ * Prototypes
+ *****************************************************************************/
/*****************************************************************************
* Function pointers
*****************************************************************************/
-typedef void (*f_motion_mb_t)( coeff_t *, pel_lookup_table_t *,
- int, coeff_t *, int, int, int, int, int );
-typedef void (*f_motion_t)( vdec_thread_t *, undec_picture_t *, int,
- f_motion_mb_t );
+struct macroblock_s;
+struct vpar_thread_s;
+
+typedef void (*f_motion_t)( struct macroblock_s* );
+typedef void (*f_chroma_motion_t)( struct macroblock_s* );
/*****************************************************************************
* Prototypes
*****************************************************************************/
-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 );
/* Input properties */
- video_parser_t * p_vpar; /* video_parser thread */
+ struct video_parser_s * p_vpar; /* video_parser thread */
#ifdef STATS
/* Statistics */
#endif
} vdec_thread_t;
+/* Move this somewhere else ASAP !! */
+#define data_t short
+
+/*****************************************************************************
+ * Function pointers
+ *****************************************************************************/
+typedef void (*f_addb_t)( elem_t*, data_t*, int );
+
/*****************************************************************************
* Prototypes
*****************************************************************************/
+struct vpar_thread_s;
/* Thread management functions */
-vdec_thread_t * vdec_CreateThread ( vpar_thread_t *p_vpar /*, int *pi_status */ );
+vdec_thread_t * vdec_CreateThread ( struct vpar_thread_s *p_vpar /*, int *pi_status */ );
void vdec_DestroyThread ( vdec_thread_t *p_vdec /*, int *pi_status */ );
/* Time management functions */
*****************************************************************************
* This rotative FIFO contains undecoded macroblocks that are to be decoded
*****************************************************************************/
+struct video_parser_s;
+
typedef struct video_fifo_s
{
vlc_mutex_t lock; /* fifo data lock */
/*****************************************************************************
* Prototypes
*****************************************************************************/
+void vpar_InitFIFO( struct vpar_thread_s * p_vpar );
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 );
/* Dynamic thread settings */
/* ?? */
+
+/*****************************************************************************
+ * LoadQuantizerScale
+ *****************************************************************************
+ * Quantizer scale factor (ISO/IEC 13818-2 7.4.2.2)
+ *****************************************************************************/
+static __inline__ void LoadQuantizerScale( struct vpar_thread_s * p_vpar )
+{
+ /* 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 )];
+}
+
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 */
/* 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;
+ picture_t * p_backw_top;
+ picture_t * p_backw_bot;
+ picture_t * p_forw_top;
+ picture_t * 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];
boolean_t b_dct_type;
} macroblock_parsing_t;
-/*****************************************************************************
- * LoadQuantizerScale
- *****************************************************************************
- * Quantizer scale factor (ISO/IEC 13818-2 7.4.2.2)
- *****************************************************************************/
-static __inline__ void LoadQuantizerScale( vpar_thread_t * p_vpar )
-{
- /* 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
*****************************************************************************/
/*****************************************************************************
* Function pointers
*****************************************************************************/
-typedef (void *) f_slice_header_t( vpar_thread_t*, int*, int, elem_t*, u32);
+struct vpar_thread_s;
+
+typedef void (*f_slice_header_t)( struct vpar_thread_s*, int*, int, elem_t*, u32);
/*****************************************************************************
* quant_matrix_t : Quantization Matrix
*****************************************************************************/
typedef struct quant_matrix_s
{
- int pi_matrix[64];
+ int * pi_matrix;
boolean_t b_allocated;
/* Has the matrix been allocated by vpar_headers ? */
} quant_matrix_t;
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 * );
+ void (*pf_decode_mv)( struct vpar_thread_s *, int );
+ void (*pf_decode_pattern)( struct vpar_thread_s * );
/* Parser context */
- picture_t * p_forward, p_backward;
+ picture_t * p_forward;
+ picture_t * p_backward;
/* Copyright extension */
boolean_t b_copyright_flag; /* Whether the following
/* Relative to the current field */
int i_coding_type, i_structure;
boolean_t b_frame_structure;
- (int *) pf_macroblock_type( vpar_thread_t * );
+ int (*pf_macroblock_type)( struct vpar_thread_s * );
boolean_t b_error;
} picture_parsing_t;
#define TOP_FIELD 1
#define BOTTOM_FIELD 2
#define FRAME_STRUCTURE 3
+
+
+/*****************************************************************************
+ * Prototypes
+ *****************************************************************************/
+int vpar_NextSequenceHeader( struct vpar_thread_s * p_vpar );
+int vpar_ParseHeader( struct vpar_thread_s * p_vpar );
*******************************************************************************/
int intf_CreateVoutThread( intf_thread_t *p_intf, char *psz_title, int i_width, int i_height )
{
+#if 0
int i_thread; /* thread index */
video_cfg_t cfg; /* thread configuration */
/* No empty place has been found */
return( -1 );
+#endif
}
*******************************************************************************/
void intf_DestroyVoutThread( intf_thread_t *p_intf, int i_thread )
{
+#if 0
#ifdef DEBUG
/* Check if thread still exists */
if( p_intf->pp_vout[i_thread] == NULL )
/* Destroy thread and marks its place as empty */
vout_DestroyThread( p_intf->pp_vout[i_thread], NULL );
p_intf->pp_vout[i_thread] = NULL;
+#endif
}
int fd;
#endif
+#if 0
/* Empty all threads array */
for( i_thread = 0; i_thread < VOUT_MAX_THREADS; i_thread++ )
{
p_intf->pp_vout[i_thread] = NULL;
}
+#endif
for( i_thread = 0; i_thread < INPUT_MAX_THREADS; i_thread++ )
{
p_intf->pp_input[i_thread] = NULL;
}
}
+#if 0
/* Destroy all remaining video output threads - all destruction orders are send,
* then all THREAD_OVER status are received */
for( i_thread = 0, b_thread = 0; i_thread < VOUT_MAX_THREADS; i_thread++ )
}
}
}
-
+#endif
}
#include "decoder_fifo.h"
#include "video.h"
#include "video_output.h"
+
+#include "vdec_idct.h"
#include "video_decoder.h"
+#include "vdec_motion.h"
+
+#include "vpar_blocks.h"
+#include "vpar_headers.h"
+#include "video_fifo.h"
#include "video_parser.h"
-#include "parser_fifo.h"
/*
* Local prototypes
p_vpar->fifo.i_end = 0;
/* Initialize the bit stream structure */
p_vpar->bit_stream.p_input = p_input;
- p_vpar->bit_stream.p_parser_fifo = &p_vpar->fifo;
+ p_vpar->bit_stream.p_decoder_fifo = &p_vpar->fifo;
p_vpar->bit_stream.fifo.buffer = 0;
p_vpar->bit_stream.fifo.i_available = 0;
#endif
/* Initialize parsing data */
- p_vpar->sequence.p_forward = p_vpar->sequence.p_backward = NULL;
- p_vpar->sequence.intra_quant.b_allocated = FALSE;
- 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;
+ p_vpar->sequence.p_forward = NULL;
+ p_vpar->sequence.p_backward = NULL;
+ p_vpar->sequence.intra_quant.b_allocated = 0;
+ p_vpar->sequence.nonintra_quant.b_allocated = 0;
+ p_vpar->sequence.chroma_intra_quant.b_allocated = 0;
+ p_vpar->sequence.chroma_nonintra_quant.b_allocated = 0;
/* Initialize copyright information */
p_vpar->sequence.b_copyright_flag = 0;
p_vpar->sequence.b_original = 0;
/* Initialize video FIFO */
vpar_InitFIFO( p_vpar );
- bzero( p_vpar->p_vdec, MAX_VDEC*sizeof(vdec_thread_t *) );
+ bzero( p_vpar->p_vdec, NB_VDEC*sizeof(vdec_thread_t *) );
/* Spawn video_decoder threads */
/* ??? modify the number of vdecs at runtime ? */
*******************************************************************************/
static void RunThread( vpar_thread_t *p_vpar )
{
- int i_dummy;
-
intf_DbgMsg("vpar debug: running video parser thread (%p) (pid == %i)\n", p_vpar, getpid());
/*
/*****************************************************************************
* vpar_NextSequenceHeader : Find the next sequence header
*****************************************************************************/
-void vpar_NextSequenceHeader( vpar_thread_t * p_vpar )
+int vpar_NextSequenceHeader( vpar_thread_t * p_vpar )
{
while( !p_vpar->b_die )
{
NextStartCode( p_vpar );
if( ShowBits( &p_vpar->bit_stream, 32 ) == SEQUENCE_START_CODE )
- return;
+ return 0;
}
+ return 1;
}
/*****************************************************************************
static __inline__ void NextStartCode( vpar_thread_t * p_vpar )
{
/* Re-align the buffer on an 8-bit boundary */
- DumpBits( &p_vpar->bit_stream, p_vpar->bit_stream.fifo.i_available & 7 );
+ RealignBits( &p_vpar->bit_stream );
while( ShowBits( &p_vpar->bit_stream, 24 ) != 0x01L && !p_vpar->b_die )
{
/* 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
( 3 - p_vpar->sequence.i_chroma_format )) );
/* Update the reference pointers. */
- ReferenceUpdate( p_vpar, i_coding_type, p_undec_p );
+ ReferenceUpdate( p_vpar, i_coding_type, p_picture );
}
p_vpar->picture.i_current_structure |= i_structure;
p_vpar->picture.i_structure = i_structure;