Commit 047ca4f8 authored by Christophe Massiot's avatar Christophe Massiot

D�but du d�codeur + d�but du parseur.

�videmment �a compile pas et on n'est pas sortis de l'auberge, m'enfin...
parent eee7f389
/*******************************************************************************
* undec_picture.h: undecoded pictures type
* (c)1999 VideoLAN
*******************************************************************************
* This header is required by all modules which have to handle pictures. It
* includes all common video types and constants.
*******************************************************************************
* Requires:
* "config.h"
* "common.h"
* "video.h"
*******************************************************************************/
/*******************************************************************************
* macroblock_info_t : information on a macroblock
*******************************************************************************/
typedef struct
{
int i_mb_type;
int i_motion_type;
int i_dct_type;
(void *) p_idct_function[12](coeff_t * p_block);
int ppp_motion_vectors[2][2][2];
int pi_field_select[2][2];
} macroblock_info_t;
/* Macroblock types */
#define MB_INTRA 1
#define MB_PATTERN 2
#define MB_MOTION_BACKWARD 4
#define MB_MOTION_FORWARD 8
#define MB_QUANT 16
/* Motion types */
#define MOTION_FIELD 1
#define MOTION_FRAME 2
#define MOTION_16X8 2
#define MOTION_DMV 3
/*******************************************************************************
* undec_link_t : link to an undecoded picture
*******************************************************************************/
typedef struct undec_link_s
{
struct undec_picture_s * p_undec;
picture_t ** pp_frame;
} undec_link_t
/*******************************************************************************
* undec_picture_t: undecoded picture
*******************************************************************************
* Any picture destined to be decoded by a video decoder thread should be
* stored in this structure from it's creation to it's effective display.
*******************************************************************************/
typedef struct undec_picture_s
{
/* Picture data */
picture_t * p_picture;
int i_coding_type;
boolean_t b_mpeg2;
int i_mb_height, i_mb_width;
int i_structure;
macroblock_info_t * p_mb_info;
picture_t * p_backward_ref;
picture_t * p_forward_ref;
undec_link_t pp_referencing_undec[MAX_REFERENCING_UNDEC];
} undec_picture_t;
/* 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_FIRST 1
#define BOTTOM_FIRST 2
#define FRAME_STRUCTURE 3
/*******************************************************************************
* pel_lookup_table_t : lookup table for pixels
*******************************************************************************/
typedef struct pel_lookup_table_s {
#ifdef BIG_PICTURES
u32 * pi_pel;
#else
u16 * pi_pel;
#endif
/* When the size of the picture changes, this structure is freed, so we
* keep a reference count. */
int i_refcount;
vlc_mutex_t lock;
} pel_lookup_table_t;
/*****************************************************************************
* vdec_motion.h : types for the motion compensation algorithm
* (c)1999 VideoLAN
*****************************************************************************
*****************************************************************************
* Requires:
* "config.h"
* "common.h"
* "vlc_thread.h"
* "video_parser.h"
* "undec_picture.h"
*****************************************************************************/
/*****************************************************************************
* 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 );
/*****************************************************************************
* 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 );
/*****************************************************************************
* video_fifo.h : FIFO for the pool of video_decoders
* (c)1999 VideoLAN
*****************************************************************************
*****************************************************************************
* Requires:
* "config.h"
* "common.h"
* "vlc_thread.h"
* "video_parser.h"
* "undec_picture.h"
*****************************************************************************/
/*****************************************************************************
* Macros
*****************************************************************************/
/* ?? move to inline functions */
#define VIDEO_FIFO_ISEMPTY( fifo ) ( (fifo).i_start == (fifo).i_end )
#define VIDEO_FIFO_ISFULL( fifo ) ( ( ( (fifo).i_end + 1 - (fifo).i_start ) \
& VFIFO_SIZE ) == 0 )
#define VIDEO_FIFO_START( fifo ) ( (fifo).buffer[ (fifo).i_start ] )
#define VIDEO_FIFO_INCSTART( fifo ) ( (fifo).i_start = ((fifo).i_start + 1) \
& VFIFO_SIZE )
#define VIDEO_FIFO_END( fifo ) ( (fifo).buffer[ (fifo).i_end ] )
#define VIDEO_FIFO_INCEND( fifo ) ( (fifo).i_end = ((fifo).i_end + 1) \
& VFIFO_SIZE )
/*****************************************************************************
* video_fifo_t
*****************************************************************************
* This rotative FIFO contains undecoded pictures that are to be decoded
*****************************************************************************/
typedef struct video_fifo_s
{
vlc_mutex_t lock; /* fifo data lock */
vlc_cond_t wait; /* fifo data conditional variable */
/* buffer is an array of undec_picture_t pointers */
undec_picture_t * buffer[VFIFO_SIZE + 1];
int i_start;
int i_end;
struct video_parser_s * p_vpar;
} video_fifo_t;
/*****************************************************************************
* video_buffer_t
*****************************************************************************
* This structure enables the parser to maintain a list of free
* undec_picture_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 */
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 );
...@@ -11,9 +11,22 @@ ...@@ -11,9 +11,22 @@
* "input.h" * "input.h"
* "video.h" * "video.h"
* "video_output.h" * "video_output.h"
* "parser_fifo.h" * "decoder_fifo.h"
* "video_fifo.h"
*******************************************************************************/ *******************************************************************************/
/*******************************************************************************
* sequence_t : sequence descriptor
*******************************************************************************
* ??
*******************************************************************************/
typedef struct sequence_s
{
u32 i_height, i_width;
unsigned int i_aspect_ratio;
double frame_rate;
} sequence_t;
/******************************************************************************* /*******************************************************************************
* vpar_thread_t: video parser thread descriptor * vpar_thread_t: video parser thread descriptor
******************************************************************************* *******************************************************************************
...@@ -35,7 +48,7 @@ typedef struct vpar_thread_s ...@@ -35,7 +48,7 @@ typedef struct vpar_thread_s
/* Input properties */ /* Input properties */
parser_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 */ /* The bit stream structure handles the PES stream at the bit level */
bit_stream_t bit_stream; bit_stream_t bit_stream;
...@@ -44,11 +57,19 @@ typedef struct vpar_thread_s ...@@ -44,11 +57,19 @@ typedef struct vpar_thread_s
vout_thread_t * p_vout; /* video output thread */ vout_thread_t * p_vout; /* video output thread */
int i_stream; /* video stream id */ int i_stream; /* video stream id */
/* Decoder properties */
struct vdec_thread_s * p_vdec[MAX_VDEC];
video_fifo_t vfifo;
video_buffer_t vbuffer;
/* Parser properties */
sequence_t sequence;
#ifdef STATS #ifdef STATS
/* Statistics */ /* Statistics */
count_t c_loops; /* number of loops */ count_t c_loops; /* number of loops */
count_t c_idle_loops; /* number of idle 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_pictures; /* number of pictures read */
count_t c_i_pictures; /* number of I 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_p_pictures; /* number of P pictures read */
...@@ -60,6 +81,19 @@ typedef struct vpar_thread_s ...@@ -60,6 +81,19 @@ typedef struct vpar_thread_s
#endif #endif
} vpar_thread_t; } 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
/******************************************************************************* /*******************************************************************************
* Prototypes * Prototypes
*******************************************************************************/ *******************************************************************************/
...@@ -67,7 +101,7 @@ typedef struct vpar_thread_s ...@@ -67,7 +101,7 @@ typedef struct vpar_thread_s
/* Thread management functions */ /* Thread management functions */
vpar_thread_t * vpar_CreateThread ( /* video_cfg_t *p_cfg, */ input_thread_t *p_input /*, vpar_thread_t * vpar_CreateThread ( /* video_cfg_t *p_cfg, */ input_thread_t *p_input /*,
vout_thread_t *p_vout, int *pi_status */ ); vout_thread_t *p_vout, int *pi_status */ );
void vpar_DestroyThread ( vpar_thread_t *p_vpar /*, int *pi_status */ ); void vpar_DestroyThread ( vpar_thread_t *p_vpar /*, int *pi_status */ );
/* Time management functions */ /* Time management functions */
/* ?? */ /* ?? */
......
/*****************************************************************************
* vdec_motion.c : motion compensation routines
* (c)1999 VideoLAN
*****************************************************************************/
/* ?? passer en terminate/destroy avec les signaux supplmentaires */
/*****************************************************************************
* 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
*/
/*****************************************************************************
* vdec_MotionCompensation : motion compensation
*****************************************************************************/
void vdec_MotionFrame( vdec_thread_t * p_vdec,
undec_picture_t * p_undec_p, int i_mb,
f_motion_mb_t pf_mb_motion )
{
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 */
#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
*****************************************************************************/
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 )
{
/* Luminance */
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] );
}
/*****************************************************************************
* MotionBlock : motion compensation for one 8x8 block
*****************************************************************************/
void __inline__ MotionBlock( 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 )
{
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 };
int i_mode;
i_mode = (i_mv_x & 1) | ((i_mv_y & 1) << 1);
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 );
}
/*****************************************************************************
* ComponentNN : motion compensation without half pel
*****************************************************************************/
void ComponentNN( 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 )
{
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;
for( i_vpos = 0; i_vpos < 8; 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;
}
}
This diff is collapsed.
/*******************************************************************************
* video_fifo.c : video FIFO management
* (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"
/*****************************************************************************
* vpar_InitFIFO : initialize the video FIFO
*****************************************************************************/
void vpar_InitFIFO( vpar_thread_t * p_vpar )
{
int i_dummy;
/* Initialize mutex and cond */
vlc_mutex_init( p_vpar->vfifo.lock );
vlc_cond_init( p_vpar->vfifo.wait );
vlc_mutex_init( p_vpar->vbuffer.lock );
/* Initialize FIFO properties */
p_vpar->vfifo.i_start = p_vpar->vfifo.i_end = 0;
p_vpar->vfifo.p_vpar = p_vpar;
/* Initialize buffer properties */
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;
}
}
/*****************************************************************************
* vpar_GetPicture : return a picture to be decoded
*****************************************************************************/
undec_picture_t * vpar_GetPicture( video_fifo_t * p_fifo )
{
undec_picture_t * p_undec_p;
vlc_mutex_lock( &p_fifo->lock );
while( VIDEO_FIFO_ISEMPTY( *p_fifo ) )
{
vlc_cond_wait( &p_fifo->wait, &p_fifo->lock );
if( p_fifo->p_vpar->b_die )
{
vlc_mutex_unlock( &p_fifo->lock );
return( NULL );
}
}
p_undec_p = VIDEO_FIFO_START( *p_fifo );
VIDEO_FIFO_INCSTART( *p_fifo );
vlc_mutex_unlock( &p_fifo->lock );
return( p_undec_p );
}
/*****************************************************************************
* vpar_NewPicture : return a buffer for the parser
*****************************************************************************/
undec_picture_t * vpar_NewPicture( video_fifo_t * p_fifo )
{
undec_picture_t * p_undec_p;
#define P_buffer p_fifo->p_vpar.vbuffer
vlc_mutex_lock( &P_buffer->lock );
if( P_buffer.i_index == -1 )
{
/* No more structures available. This should not happen ! */
return NULL;
}
p_undec_p = P_buffer->pp_undec_free[ P_buffer->i_index-- ];
#undef P_buffer
vlc_mutex_unlock( &P_buffer->lock );
return( p_undec_p );
}
/*****************************************************************************
* vpar_DecodePicture : put a picture in the video fifo, if it is decodable
*****************************************************************************/
void vpar_DecodePicture( video_fifo_t * p_fifo, undec_picture_t * p_undec_p )
{
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 );
/* By construction, the video FIFO cannot be full */
VIDEO_FIFO_END( *p_fifo ) = p_undec_p;
VIDEO_FIFO_INCEND( *p_fifo );
vlc_mutex_unlock( &p_fifo->lock );
}
}
/*****************************************************************************
* vpar_ReleasePicture : put a picture in the video_output fifo, and update
* links and buffers
*****************************************************************************/
void vpar_ReleasePicture( video_fifo_t * p_fifo, undec_picture_t * p_undec_p )
{
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++ )
{
*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 );
}
/* Unlink referenced pictures */
if( p_undec_p->p_forward_ref != 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 );
}
}
/* Mark the picture to be displayed */
vout_DisplayPicture( p_fifo->p_vpar.p_vout, p_undec_p->p_picture );
/* Release the undec_picture_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;
vlc_mutex_unlock( &P_buffer->lock );
#undef P_buffer
}
}
/*****************************************************************************
* vpar_DestroyPicture : destroy a picture in case of error
*****************************************************************************/
void vpar_DestroyPicture( video_fifo_t * p_fifo, undec_picture_t * p_undec_p )
{
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++ )
{
/* Try to put the referencing picture in the video FIFO */
vpar_DestroyPicture( p_fifo, p_undec_p->pp_referencing_undec[i_ref].p_undec );
}
/* Unlink referenced pictures */
if( p_undec_p->p_forward_ref != 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 );
}
}
/* Release the picture buffer */
vout_DestroyPicture( p_fifo->p_vpar.p_vout, p_undec_p->p_picture );
/* Release the undec_picture_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;
vlc_mutex_unlock( &P_buffer->lock );
#undef P_buffer
}
}
...@@ -104,7 +104,7 @@ vpar_thread_t * vpar_CreateThread( /* video_cfg_t *p_cfg, */ input_thread_t *p_i ...@@ -104,7 +104,7 @@ vpar_thread_t * vpar_CreateThread( /* video_cfg_t *p_cfg, */ input_thread_t *p_i
* be destroyed, and non 0 else. The last case probably means that the thread * be destroyed, and non 0 else. The last case probably means that the thread
* was still active, and another try may succeed. * was still active, and another try may succeed.
*******************************************************************************/ *******************************************************************************/
void vpar g_DestroyThread( vpar_thread_t *p_vpar /*, int *pi_status */ ) void vpar_DestroyThread( vpar_thread_t *p_vpar /*, int *pi_status */ )
{ {
intf_DbgMsg("vpar debug: requesting termination of video parser thread %p\n", p_vpar); intf_DbgMsg("vpar debug: requesting termination of video parser thread %p\n", p_vpar);
...@@ -152,11 +152,11 @@ static int InitThread( vpar_thread_t *p_vpar ) ...@@ -152,11 +152,11 @@ static int InitThread( vpar_thread_t *p_vpar )
/* Our first job is to initialize the bit stream structure with the /* Our first job is to initialize the bit stream structure with the
* beginning of the input stream */ * beginning of the input stream */
vlc_mutex_lock( &p_vpar->fifo.data_lock ); vlc_mutex_lock( &p_vpar->fifo.data_lock );
while ( PARSER_FIFO_ISEMPTY(p_vpar->fifo) ) while ( DECODER_FIFO_ISEMPTY(p_vpar->fifo) )
{ {
vlc_cond_wait( &p_vpar->fifo.data_wait, &p_vpar->fifo.data_lock ); vlc_cond_wait( &p_vpar->fifo.data_wait, &p_vpar->fifo.data_lock );
} }
p_vpar->bit_stream.p_ts = PARSER_FIFO_START( p_vpar->fifo )->p_first_ts; p_vpar->bit_stream.p_ts = DECODER_FIFO_START( p_vpar->fifo )->p_first_ts;
p_vpar->bit_stream.i_byte = p_vpar->bit_stream.p_ts->i_payload_start; p_vpar->bit_stream.i_byte = p_vpar->bit_stream.p_ts->i_payload_start;
vlc_mutex_unlock( &p_vpar->fifo.data_lock ); vlc_mutex_unlock( &p_vpar->fifo.data_lock );
...@@ -187,24 +187,37 @@ static int InitThread( vpar_thread_t *p_vpar ) ...@@ -187,24 +187,37 @@ static int InitThread( vpar_thread_t *p_vpar )
p_vpar->c_decoded_b_pictures = 0; p_vpar->c_decoded_b_pictures = 0;
#endif #endif
/* Initialize video FIFO */
vpar_InitFIFO( p_vpar );
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 )
{
return( 1 );
}
/* Mark thread as running and return */ /* Mark thread as running and return */
intf_DbgMsg("vpar debug: InitThread(%p) succeeded\n", p_vpar); intf_DbgMsg("vpar debug: InitThread(%p) succeeded\n", p_vpar);
return( 0 ); return( 0 );
} }
/******************************************************************************* /*******************************************************************************
* RunThread: generic parser thread * RunThread: generic parser thread
******************************************************************************* *******************************************************************************
* Generic parser thread. This function does only returns when the thread is * Video parser thread. This function does only returns when the thread is
* terminated. * terminated.
*******************************************************************************/ *******************************************************************************/
static void RunThread( vpar_thread_t *p_vpar ) 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()); intf_DbgMsg("vpar debug: running video parser thread (%p) (pid == %i)\n", p_vpar, getpid());
/* /*
* Initialize thread and free configuration * Initialize thread
*/ */
p_vpar->b_error = InitThread( p_vpar ); p_vpar->b_error = InitThread( p_vpar );
if( p_vpar->b_error ) if( p_vpar->b_error )
...@@ -213,16 +226,28 @@ static void RunThread( vpar_thread_t *p_vpar ) ...@@ -213,16 +226,28 @@ static void RunThread( vpar_thread_t *p_vpar )
} }
p_vpar->b_run = 1; p_vpar->b_run = 1;
/* REMOVE ME !!!!! */
p_vpar->b_error = 1;
/* /*
* Main loop - it is not executed if an error occured during * Main loop - it is not executed if an error occured during
* initialization * initialization
*/ */
while( (!p_vpar->b_die) && (!p_vpar->b_error) ) while( (!p_vpar->b_die) && (!p_vpar->b_error) )
{ {
/* ?? */ /* Find the next sequence header in the stream */
p_vpar->b_error = vpar_NextSequenceHeader( p_vpar );
#ifdef STATS
p_vpar->c_sequences++;
#endif
while( (!p_vpar->b_die) && (!p_vpar->b_error) )
{
/* Parse the next sequence, group or picture header */
if( vpar_ParseHeader( p_vpar ) )
{
/* End of sequence */
break;
};
}
} }
/* /*
...@@ -275,6 +300,8 @@ static void ErrorThread( vpar_thread_t *p_vpar ) ...@@ -275,6 +300,8 @@ static void ErrorThread( vpar_thread_t *p_vpar )
*******************************************************************************/ *******************************************************************************/
static void EndThread( vpar_thread_t *p_vpar ) static void EndThread( vpar_thread_t *p_vpar )
{ {
int i_dummy;
intf_DbgMsg("vpar debug: destroying video parser thread %p\n", p_vpar); intf_DbgMsg("vpar debug: destroying video parser thread %p\n", p_vpar);
#ifdef DEBUG #ifdef DEBUG
...@@ -286,5 +313,14 @@ static void EndThread( vpar_thread_t *p_vpar ) ...@@ -286,5 +313,14 @@ static void EndThread( vpar_thread_t *p_vpar )
// vout_DestroyStream( p_vpar->p_vout, p_vpar->i_stream ); // vout_DestroyStream( p_vpar->p_vout, p_vpar->i_stream );
/* ?? */ /* ?? */
/* Destroy vdec threads */
for( i_dummy = 0; i_dummy < MAX_VDEC; i_dummy++ )
{
if( p_vpar->p_vdec[i_dummy] != NULL )
vdec_DestroyThread( p_vpar->p_vdec[i_dummy] );
else
break;
}
intf_DbgMsg("vpar debug: EndThread(%p)\n", p_vpar); intf_DbgMsg("vpar debug: EndThread(%p)\n", p_vpar);
} }
/*****************************************************************************
* vpar_headers.c : headers parsing
* (c)1999 VideoLAN
*****************************************************************************/
/* ?? passer en terminate/destroy avec les signaux supplmentaires */
/*****************************************************************************
* 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
*/
/*****************************************************************************
* vpar_NextSequenceHeader : Find the next sequence header
*****************************************************************************/
void 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;
}
}
/*****************************************************************************
* vpar_ParseHeader : Parse the next header
*****************************************************************************/
int vpar_ParseHeader( vpar_thread_t * p_vpar )
{
while( !p_vpar->b_die )
{
NextStartCode( p_vpar );
switch( GetBits32( &p_vpar->bit_stream ) )
{
case SEQUENCE_HEADER_CODE:
SequenceHeader( p_vpar );
return 0;
break;
case GROUP_START_CODE:
GroupHeader( p_vpar );
return 0;
break;
case PICTURE_START_CODE:
PictureHeader( p_vpar );
return 0;
break;
case SEQUENCE_END_CODE:
return 1;
break;
default:
}
}
return 0;
}
/*
* Following functions are local
*/
/*****************************************************************************
* NextStartCode : Find the next start code
*****************************************************************************/
static __inline__ void NextStartCode( vpar_thread_t * p_vpar )
{
/* Re-align the buffer to 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 )
{
DumpBits( &p_vpar->bit_stream, 8 );
}
}
/*****************************************************************************
* SequenceHeader : Parse the next sequence header
*****************************************************************************/
static void SequenceHeader( vpar_thread_t * p_vpar )
{
int i_frame_rate_code;
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_ratio = GetBits( p_vpar->bit_stream, 4 );
i_frame_rate_code = GetBits( p_vpar->bit_stream, 4 );
/* We don't need bit_rate_value, marker_bit, vbv_buffer_size,
* constrained_parameters_flag */
DumpBits( p_vpar->bits_stream, 30 );
}
/*****************************************************************************
* GroupHeader : Parse the next group of pictures header
*****************************************************************************/
static void GroupHeader( vpar_thread_t * p_vpar )
{
}
/*****************************************************************************
* PictureHeader : Parse the next picture header
*****************************************************************************/
static void PictureHeader( vpar_thread_t * p_vpar )
{
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment