Mpgv.c 是对mpeg vedio的解码部分,从demux开始,到sample到输出。其中,核心部分是函数ParseMPEGBlock。
两种数据格式:video_format 是video的meta_data,block是实际的数据
Code Path:
Open()----->
Modules/demux/Mpgv.c
1)set function point. p_sys is main structure
p_demux->pf_demux = Demux;
p_demux->pf_control= Control;
p_demux->p_sys = p_sys = malloc( sizeof( demux_sys_t ) );
2)create demux object
p_sys->p_packetizer = vlc_object_create( p_demux, VLC_OBJECT_PACKETIZER );
3)create packetizer
decoder_t p_packetizer
struct decoder_t
{
VLC_COMMON_MEMBERS
/* Module properties */
module_t * p_module;
decoder_sys_t * p_sys;
/* Input format ie from demuxer (XXX: a lot of field could be invalid) */
es_format_t fmt_in;
/* Output format of decoder/packetizer */
es_format_t fmt_out;
/* Some decoders only accept packetized data (ie. not truncated) */
vlc_bool_t b_need_packetized;
/* Tell the decoder if it is allowed to drop frames */
vlc_bool_t b_pace_control;
picture_t * ( * pf_decode_video )( decoder_t *, block_t ** );
aout_buffer_t * ( * pf_decode_audio )( decoder_t *, block_t ** );
subpicture_t * ( * pf_decode_sub) ( decoder_t *, block_t ** );
block_t * ( * pf_packetize ) ( decoder_t *, block_t ** );
... ...
}
4) es_format_Init( &p_sys->p_packetizer->fmt_in, VIDEO_ES,
VLC_FOURCC( 'm', 'p', 'g', 'v' ) );
5) p_sys->p_packetizer->p_module =
module_Need( p_sys->p_packetizer, "packetizer", NULL, 0 );
Demux()----->
Modules/demux/Mpgv.c
1)get a whole package
if( ( p_block_in = stream_Block( p_demux->s, MPGV_PACKET_SIZE ) ) == NULL )
2)packetize it, demux it
while( (p_block_out = p_sys->p_packetizer->pf_packetize( p_sys->p_packetizer, &p_block_in )) )
{
p_sys->b_start = VLC_FALSE;
while( p_block_out )
{
block_t *p_next = p_block_out->p_next;
es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_block_out->i_dts );
p_block_out->p_next = NULL;
//send to next filter to handle it
es_out_Send( p_demux->out, p_sys->p_es, p_block_out );
p_block_out = p_next;
}
}
pf_packetize() is make stream to package and parse it
pf_packetize() -->
/Packetizer/mpegvideo.c
static block_t *Packetize( decoder_t *p_dec, block_t **pp_block )
decoder_sys_t *p_sys = p_dec->p_sys;
while( 1 )
{
switch( p_sys->i_state )
{
case STATE_NOSYNC:
case STATE_NEXT_SYNC:
/* Get the new fragment and set the pts/dts */
p_pic = block_New( p_dec, p_sys->i_offset );
block_BytestreamFlush( &p_sys->bytestream );
if( !( p_pic = ParseMPEGBlock( p_dec, p_pic ) ) )
{
p_sys->i_state = STATE_NOSYNC;
break;
}
}
}
ParseMPEGBlock()-->
/Packetizer/mpegvideo.c
parse data to get something
es_out_Control() and es_out_Send() call next filter to transfer pictures
/include/Vlc_es.h
/**
* ES definition
*/
struct es_format_t
{
int i_cat;
vlc_fourcc_t i_codec;
int i_id; /* -1: let the core mark the right id
>=0: valid id */
int i_group; /* -1 : standalone
>= 0 then a "group" (program) is created
for each value */
int i_priority; /* -2 : mean not selectable by the users
-1 : mean not selected by default even
when no other stream
>=0: priority */
char *psz_language;
char *psz_description;
audio_format_t audio;
video_format_t video;
subs_format_t subs;
unsigned int i_bitrate;
vlc_bool_t b_packetized; /* wether the data is packetized
(ie. not truncated) */
int i_extra;
void *p_extra;
};
/include/Vlc_common.h
/**
* The vlc_fourcc_t type.
*
* See http://www.webartz.com/fourcc/ for a very detailed list.
*/
typedef uint32_t vlc_fourcc_t;
/include/Vlc_es.h
struct audio_format_t
{
vlc_fourcc_t i_format; /**< audio format fourcc */
unsigned int i_rate; /**< audio sample-rate */
/* Describes the channels configuration of the samples (ie. number of
* channels which are available in the buffer, and positions). */
uint32_t i_physical_channels;
/* Describes from which original channels, before downmixing, the
* buffer is derived. */
uint32_t i_original_channels;
/* Optional - for A/52, SPDIF and DTS types : */
/* Bytes used by one compressed frame, depends on bitrate. */
unsigned int i_bytes_per_frame;
/* Number of sampleframes contained in one compressed frame. */
unsigned int i_frame_length;
/* Please note that it may be completely arbitrary - buffers are not
* obliged to contain a integral number of so-called "frames". It's
* just here for the division :
* buffer_size = i_nb_samples * i_bytes_per_frame / i_frame_length
*/
/* FIXME ? (used by the codecs) */
int i_channels;
int i_blockalign;
int i_bitspersample;
};
/**
* video format description
*/
struct video_format_t
{
vlc_fourcc_t i_chroma; /**< picture chroma */
unsigned int i_aspect; /**< aspect ratio */
unsigned int i_width; /**< picture width */
unsigned int i_height; /**< picture height */
unsigned int i_x_offset; /**< start offset of visible area */
unsigned int i_y_offset; /**< start offset of visible area */
unsigned int i_visible_width; /**< width of visible area */
unsigned int i_visible_height; /**< height of visible area */
unsigned int i_bits_per_pixel; /**< number of bits per pixel */
unsigned int i_sar_num; /**< sample/pixel aspect ratio */
unsigned int i_sar_den;
unsigned int i_frame_rate; /**< frame rate numerator */
unsigned int i_frame_rate_base; /**< frame rate denominator */
int i_rmask, i_gmask, i_bmask; /**< color masks for RGB chroma */
video_palette_t *p_palette; /**< video palette from demuxer */
};
/include/Vlc_block.h
struct block_t
{
block_t *p_next;
block_t *p_prev;
uint32_t i_flags;
mtime_t i_pts;
mtime_t i_dts;
mtime_t i_length;
int i_samples; /* Used for audio */
int i_rate;
int i_buffer;
uint8_t *p_buffer;
/* This way the block_Release can be overloaded
* Don't mess with it now, if you need it the ask on ML
*/
void (*pf_release) ( block_t * );
/* It's an object that should be valid as long as the block_t is valid */
/* It should become a true block manager to reduce malloc/free */
vlc_object_t *p_manager;
/* Following fields are private, user should never touch it */
/* XXX never touch that OK !!! the first that access that will
* have cvs account removed ;) XXX */
block_sys_t *p_sys;
};