vlc代码分析(4)——mpgv的demux

Posted on 2006-12-28 02:06  Teddy Yan  阅读(811)  评论(0编辑  收藏  举报

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;
}; 

Copyright © 2024 Teddy Yan
Powered by .NET 8.0 on Kubernetes