⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mpegvideo.c

📁 video linux conference
💻 C
📖 第 1 页 / 共 2 页
字号:
/***************************************************************************** * mpegvideo.c: parse and packetize an MPEG1/2 video stream ***************************************************************************** * Copyright (C) 2001, 2002 VideoLAN * $Id: mpegvideo.c 10101 2005-03-02 16:47:31Z robux4 $ * * Authors: Laurent Aimar <fenrir@via.ecp.fr> *          Eric Petit <titer@videolan.org> *          Gildas Bazin <gbazin@videolan.org> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA. *****************************************************************************//***************************************************************************** * Problem with this implementation: * * Although we should time-stamp each picture with a PTS, this isn't possible * with the current implementation. * The problem comes from the fact that for non-low-delay streams we can't * calculate the PTS of pictures used as backward reference. Even the temporal * reference number doesn't help here because all the pictures don't * necessarily have the same duration (eg. 3:2 pulldown). * * However this doesn't really matter as far as the MPEG muxers are concerned * because they allow having empty PTS fields. --gibalou *****************************************************************************//***************************************************************************** * Preamble *****************************************************************************/#include <stdlib.h>                                      /* malloc(), free() */#include <vlc/vlc.h>#include <vlc/decoder.h>#include <vlc/input.h>#include "vlc_block_helper.h"/***************************************************************************** * Module descriptor *****************************************************************************/static int  Open ( vlc_object_t * );static void Close( vlc_object_t * );vlc_module_begin();    set_category( CAT_SOUT );    set_subcategory( SUBCAT_SOUT_PACKETIZER );    set_description( _("MPEG-I/II video packetizer") );    set_capability( "packetizer", 50 );    set_callbacks( Open, Close );vlc_module_end();/***************************************************************************** * Local prototypes *****************************************************************************/static block_t *Packetize( decoder_t *, block_t ** );static block_t *ParseMPEGBlock( decoder_t *, block_t * );struct decoder_sys_t{    /*     * Input properties     */    block_bytestream_t bytestream;    int i_state;    int i_offset;    uint8_t p_startcode[3];    /* Sequence header and extension */    block_t *p_seq;    block_t *p_ext;    /* Current frame being built */    block_t    *p_frame;    block_t    **pp_last;    vlc_bool_t b_frame_slice;    mtime_t i_pts;    mtime_t i_dts;    /* Sequence properties */    int         i_frame_rate;    int         i_frame_rate_base;    vlc_bool_t  b_seq_progressive;    vlc_bool_t  b_low_delay;    int         i_aspect_ratio_info;    vlc_bool_t  b_inited;    /* Picture properties */    int i_temporal_ref;    int i_picture_type;    int i_picture_structure;    int i_top_field_first;    int i_repeat_first_field;    int i_progressive_frame;    mtime_t i_interpolated_dts;    mtime_t i_old_duration;    mtime_t i_last_ref_pts;    /* Number of pictures since last sequence header */    int i_seq_old;};enum {    STATE_NOSYNC,    STATE_NEXT_SYNC};/***************************************************************************** * Open: *****************************************************************************/static int Open( vlc_object_t *p_this ){    decoder_t *p_dec = (decoder_t*)p_this;    decoder_sys_t *p_sys;    if( p_dec->fmt_in.i_codec != VLC_FOURCC( 'm', 'p', 'g', '1' ) &&        p_dec->fmt_in.i_codec != VLC_FOURCC( 'm', 'p', 'g', '2' ) &&        p_dec->fmt_in.i_codec != VLC_FOURCC( 'm', 'p', 'g', 'v' ) )    {        return VLC_EGENERIC;    }    es_format_Init( &p_dec->fmt_out, VIDEO_ES, VLC_FOURCC('m','p','g','v') );    p_dec->pf_packetize = Packetize;    p_dec->p_sys = p_sys = malloc( sizeof( decoder_sys_t ) );    /* Misc init */    p_sys->i_state = STATE_NOSYNC;    p_sys->bytestream = block_BytestreamInit( p_dec );    p_sys->p_startcode[0] = 0;    p_sys->p_startcode[1] = 0;    p_sys->p_startcode[2] = 1;    p_sys->i_offset = 0;    p_sys->p_seq = NULL;    p_sys->p_ext = NULL;    p_sys->p_frame = NULL;    p_sys->pp_last = &p_sys->p_frame;    p_sys->b_frame_slice = VLC_FALSE;    p_sys->i_dts = p_sys->i_pts = 0;    p_sys->i_frame_rate = 1;    p_sys->i_frame_rate_base = 1;    p_sys->b_seq_progressive = VLC_TRUE;    p_sys->b_low_delay = VLC_TRUE;    p_sys->i_seq_old = 0;    p_sys->i_temporal_ref = 0;    p_sys->i_picture_type = 0;    p_sys->i_picture_structure = 0x03; /* frame */    p_sys->i_top_field_first = 0;    p_sys->i_repeat_first_field = 0;    p_sys->i_progressive_frame = 0;    p_sys->b_inited = 0;    p_sys->i_interpolated_dts = 0;    p_sys->i_old_duration = 0;    p_sys->i_last_ref_pts = 0;    return VLC_SUCCESS;}/***************************************************************************** * Close: *****************************************************************************/static void Close( vlc_object_t *p_this ){    decoder_t     *p_dec = (decoder_t*)p_this;    decoder_sys_t *p_sys = p_dec->p_sys;    block_BytestreamRelease( &p_sys->bytestream );    if( p_sys->p_seq )    {        block_Release( p_sys->p_seq );    }    if( p_sys->p_ext )    {        block_Release( p_sys->p_ext );    }    if( p_sys->p_frame )    {        block_ChainRelease( p_sys->p_frame );    }    free( p_sys );}/***************************************************************************** * Packetize: *****************************************************************************/static block_t *Packetize( decoder_t *p_dec, block_t **pp_block ){    decoder_sys_t *p_sys = p_dec->p_sys;    block_t       *p_pic;    if( pp_block == NULL || *pp_block == NULL )    {        return NULL;    }    if( (*pp_block)->i_flags & BLOCK_FLAG_DISCONTINUITY )    {        p_sys->i_state = STATE_NOSYNC;        if( p_sys->p_frame ) block_ChainRelease( p_sys->p_frame );        p_sys->p_frame = NULL;        p_sys->pp_last = &p_sys->p_frame;        p_sys->b_frame_slice = VLC_FALSE;        block_Release( *pp_block );        return NULL;    }    block_BytestreamPush( &p_sys->bytestream, *pp_block );    while( 1 )    {        switch( p_sys->i_state )        {        case STATE_NOSYNC:            if( block_FindStartcodeFromOffset( &p_sys->bytestream,                    &p_sys->i_offset, p_sys->p_startcode, 3 ) == VLC_SUCCESS )            {                p_sys->i_state = STATE_NEXT_SYNC;            }            if( p_sys->i_offset )            {                block_SkipBytes( &p_sys->bytestream, p_sys->i_offset );                p_sys->i_offset = 0;                block_BytestreamFlush( &p_sys->bytestream );            }            if( p_sys->i_state != STATE_NEXT_SYNC )            {                /* Need more data */                return NULL;            }            p_sys->i_offset = 1; /* To find next startcode */        case STATE_NEXT_SYNC:            /* TODO: If p_block == NULL, flush the buffer without checking the             * next sync word */            /* Find the next startcode */            if( block_FindStartcodeFromOffset( &p_sys->bytestream,                    &p_sys->i_offset, p_sys->p_startcode, 3 ) != VLC_SUCCESS )            {                /* Need more data */                return NULL;            }            /* Get the new fragment and set the pts/dts */            p_pic = block_New( p_dec, p_sys->i_offset );            block_BytestreamFlush( &p_sys->bytestream );            p_pic->i_pts = p_sys->bytestream.p_block->i_pts;            p_pic->i_dts = p_sys->bytestream.p_block->i_dts;            block_GetBytes( &p_sys->bytestream, p_pic->p_buffer,                            p_pic->i_buffer );            /* don't reuse the same timestamps several times */            if( p_pic->i_buffer >= 4 && p_pic->p_buffer[3] == 0x00 )            {                /* We have a picture start code */                p_sys->bytestream.p_block->i_pts = 0;                p_sys->bytestream.p_block->i_dts = 0;            }            p_sys->i_offset = 0;            /* Get picture if any */            if( !( p_pic = ParseMPEGBlock( p_dec, p_pic ) ) )            {                p_sys->i_state = STATE_NOSYNC;                break;            }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -