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

📄 avi.c

📁 video linux conference
💻 C
📖 第 1 页 / 共 2 页
字号:
/***************************************************************************** * avi.c ***************************************************************************** * Copyright (C) 2001, 2002 VideoLAN * $Id: avi.c 10101 2005-03-02 16:47:31Z robux4 $ * * Authors: Laurent Aimar <fenrir@via.ecp.fr> * * 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. *****************************************************************************//***************************************************************************** * Preamble *****************************************************************************//* TODO: add OpenDML write support */#include <stdlib.h>#include <vlc/vlc.h>#include <vlc/input.h>#include <vlc/sout.h>#include "codecs.h"/***************************************************************************** * Module descriptor *****************************************************************************/static int  Open   ( vlc_object_t * );static void Close  ( vlc_object_t * );vlc_module_begin();    set_description( _("AVI muxer") );    set_category( CAT_SOUT );    set_subcategory( SUBCAT_SOUT_MUX );    set_capability( "sout mux", 5 );    add_shortcut( "avi" );    set_callbacks( Open, Close );vlc_module_end();/***************************************************************************** * Local prototypes *****************************************************************************/static int Control( sout_mux_t *, int, va_list );static int AddStream( sout_mux_t *, sout_input_t * );static int DelStream( sout_mux_t *, sout_input_t * );static int Mux      ( sout_mux_t * );typedef struct avi_stream_s{    int i_cat;    char fcc[4];    mtime_t i_duration;       // in 祍    int     i_frames;        // total frame count    int64_t i_totalsize;    // total stream size    float   f_fps;    int     i_bitrate;    BITMAPINFOHEADER    *p_bih;    WAVEFORMATEX        *p_wf;} avi_stream_t;typedef struct avi_idx1_entry_s{    char     fcc[4];    uint32_t i_flags;    uint32_t i_pos;    uint32_t i_length;} avi_idx1_entry_t;typedef struct avi_idx1_s{    unsigned int i_entry_count;    unsigned int i_entry_max;    avi_idx1_entry_t *entry;} avi_idx1_t;struct sout_mux_sys_t{    vlc_bool_t b_write_header;    int i_streams;    int i_stream_video;    off_t i_movi_size;    avi_stream_t stream[100];    avi_idx1_t idx1;    off_t i_idx1_size;};// FIXME FIXME#define HDR_SIZE 10240/* Flags in avih */#define AVIF_HASINDEX       0x00000010  // Index at end of file?#define AVIF_ISINTERLEAVED  0x00000100#define AVIF_TRUSTCKTYPE    0x00000800  // Use CKType to find key frames?/* Flags for index */#define AVIIF_KEYFRAME      0x00000010L /* this frame is a key frame.*/static block_t *avi_HeaderCreateRIFF( sout_mux_t * );static block_t *avi_HeaderCreateidx1( sout_mux_t * );static void SetFCC( uint8_t *p, char *fcc ){    memcpy( p, fcc, 4 );}/***************************************************************************** * Open: *****************************************************************************/static int Open( vlc_object_t *p_this ){    sout_mux_t      *p_mux = (sout_mux_t*)p_this;    sout_mux_sys_t  *p_sys = p_mux->p_sys;    msg_Dbg( p_mux, "AVI muxer opened" );    p_sys = malloc( sizeof( sout_mux_sys_t ) );    p_sys->i_streams = 0;    p_sys->i_stream_video = -1;    p_sys->i_movi_size = 0;    p_sys->idx1.i_entry_count = 0;    p_sys->idx1.i_entry_max = 10000;    p_sys->idx1.entry = calloc( p_sys->idx1.i_entry_max,                                sizeof( avi_idx1_entry_t ) );    p_sys->b_write_header = VLC_TRUE;    p_mux->pf_control   = Control;    p_mux->pf_addstream = AddStream;    p_mux->pf_delstream = DelStream;    p_mux->pf_mux       = Mux;    p_mux->p_sys        = p_sys;    return VLC_SUCCESS;}/***************************************************************************** * Close: *****************************************************************************/static void Close( vlc_object_t * p_this ){    sout_mux_t      *p_mux = (sout_mux_t*)p_this;    sout_mux_sys_t  *p_sys = p_mux->p_sys;    block_t       *p_hdr, *p_idx1;    int                 i_stream;    msg_Dbg( p_mux, "AVI muxer closed" );    /* first create idx1 chunk (write at the end of the stream */    p_idx1 = avi_HeaderCreateidx1( p_mux );    p_sys->i_idx1_size = p_idx1->i_buffer;    sout_AccessOutWrite( p_mux->p_access, p_idx1 );    /* calculate some value for headers creations */    for( i_stream = 0; i_stream < p_sys->i_streams; i_stream++ )    {        avi_stream_t *p_stream;        p_stream = &p_sys->stream[i_stream];        p_stream->f_fps = 25;        if( p_stream->i_duration > 0 )        {            p_stream->f_fps = (float)p_stream->i_frames /                              ( (float)p_stream->i_duration /                                (float)1000000 );        }        p_stream->i_bitrate = 128 * 1024;        if( p_stream->i_duration > 0 )        {            p_stream->i_bitrate =                8 * (uint64_t)1000000 *                    (uint64_t)p_stream->i_totalsize /                    (uint64_t)p_stream->i_duration;        }        msg_Info( p_mux, "stream[%d] duration:"I64Fd" totalsize:"I64Fd                  " frames:%d fps:%f kb/s:%d",                  i_stream,                  (int64_t)p_stream->i_duration / (int64_t)1000000,                  p_stream->i_totalsize,                  p_stream->i_frames,                  p_stream->f_fps, p_stream->i_bitrate/1024 );    }    p_hdr = avi_HeaderCreateRIFF( p_mux );    sout_AccessOutSeek( p_mux->p_access, 0 );    sout_AccessOutWrite( p_mux->p_access, p_hdr );}static int Control( sout_mux_t *p_mux, int i_query, va_list args ){    vlc_bool_t *pb_bool;    char **ppsz;   switch( i_query )   {       case MUX_CAN_ADD_STREAM_WHILE_MUXING:           pb_bool = (vlc_bool_t*)va_arg( args, vlc_bool_t * );           *pb_bool = VLC_FALSE;           return VLC_SUCCESS;       case MUX_GET_ADD_STREAM_WAIT:           pb_bool = (vlc_bool_t*)va_arg( args, vlc_bool_t * );           *pb_bool = VLC_TRUE;           return VLC_SUCCESS;       case MUX_GET_MIME:           ppsz = (char**)va_arg( args, char ** );           *ppsz = strdup( "video/avi" );           return VLC_SUCCESS;        default:            return VLC_EGENERIC;   }}static int AddStream( sout_mux_t *p_mux, sout_input_t *p_input ){    sout_mux_sys_t  *p_sys = p_mux->p_sys;    avi_stream_t    *p_stream;    if( p_sys->i_streams >= 100 )    {        msg_Err( p_mux, "too many streams" );        return( -1 );    }    msg_Dbg( p_mux, "adding input" );    p_input->p_sys = malloc( sizeof( int ) );    *((int*)p_input->p_sys) = p_sys->i_streams;    p_stream = &p_sys->stream[p_sys->i_streams];    switch( p_input->p_fmt->i_cat )    {        case AUDIO_ES:            p_stream->i_cat = AUDIO_ES;            p_stream->fcc[0] = '0' + p_sys->i_streams / 10;            p_stream->fcc[1] = '0' + p_sys->i_streams % 10;            p_stream->fcc[2] = 'w';            p_stream->fcc[3] = 'b';            p_stream->p_bih = NULL;            p_stream->p_wf  = malloc( sizeof( WAVEFORMATEX ) +                                      p_input->p_fmt->i_extra );#define p_wf p_stream->p_wf            p_wf->cbSize = p_input->p_fmt->i_extra;            if( p_wf->cbSize > 0 )            {                memcpy( &p_wf[1],                        p_input->p_fmt->p_extra,                        p_input->p_fmt->i_extra );            }            p_wf->nChannels      = p_input->p_fmt->audio.i_channels;            p_wf->nSamplesPerSec = p_input->p_fmt->audio.i_rate;            p_wf->nBlockAlign    = p_input->p_fmt->audio.i_blockalign;            p_wf->nAvgBytesPerSec= p_input->p_fmt->i_bitrate / 8;            p_wf->wBitsPerSample = 0;            switch( p_input->p_fmt->i_codec )            {                case VLC_FOURCC( 'a', '5', '2', ' ' ):                    p_wf->wFormatTag = WAVE_FORMAT_A52;                    break;                case VLC_FOURCC( 'm', 'p', 'g', 'a' ):                    p_wf->wFormatTag = WAVE_FORMAT_MPEGLAYER3;                    break;                case VLC_FOURCC( 'w', 'm', 'a', '1' ):                    p_wf->wFormatTag = WAVE_FORMAT_WMA1;                    break;                case VLC_FOURCC( 'w', 'm', 'a', ' ' ):                case VLC_FOURCC( 'w', 'm', 'a', '2' ):                    p_wf->wFormatTag = WAVE_FORMAT_WMA2;                    break;                case VLC_FOURCC( 'w', 'm', 'a', 'p' ):                    p_wf->wFormatTag = WAVE_FORMAT_WMAP;                    break;                case VLC_FOURCC( 'w', 'm', 'a', 'l' ):                    p_wf->wFormatTag = WAVE_FORMAT_WMAL;                    break;                    /* raw codec */                case VLC_FOURCC( 'u', '8', ' ', ' ' ):                    p_wf->wFormatTag = WAVE_FORMAT_PCM;                    p_wf->nBlockAlign= p_wf->nChannels;                    p_wf->wBitsPerSample = 8;                    break;                case VLC_FOURCC( 's', '1', '6', 'l' ):                    p_wf->wFormatTag = WAVE_FORMAT_PCM;                    p_wf->nBlockAlign= 2 * p_wf->nChannels;                    p_wf->wBitsPerSample = 16;                    break;                case VLC_FOURCC( 's', '2', '4', 'l' ):                    p_wf->wFormatTag = WAVE_FORMAT_PCM;                    p_wf->nBlockAlign= 3 * p_wf->nChannels;                    p_wf->wBitsPerSample = 24;                    break;                case VLC_FOURCC( 's', '3', '2', 'l' ):                    p_wf->wFormatTag = WAVE_FORMAT_PCM;                    p_wf->nBlockAlign= 4 * p_wf->nChannels;                    p_wf->wBitsPerSample = 32;                    break;                default:                    return VLC_EGENERIC;            }#undef p_wf            break;        case VIDEO_ES:            p_stream->i_cat = VIDEO_ES;            p_stream->fcc[0] = '0' + p_sys->i_streams / 10;            p_stream->fcc[1] = '0' + p_sys->i_streams % 10;            p_stream->fcc[2] = 'd';            p_stream->fcc[3] = 'c';            if( p_sys->i_stream_video < 0 )            {                p_sys->i_stream_video = p_sys->i_streams;            }            p_stream->p_wf  = NULL;            p_stream->p_bih = malloc( sizeof( BITMAPINFOHEADER ) +                                      p_input->p_fmt->i_extra );#define p_bih p_stream->p_bih            p_bih->biSize  = sizeof( BITMAPINFOHEADER ) +                             p_input->p_fmt->i_extra;            if( p_input->p_fmt->i_extra > 0 )            {                memcpy( &p_bih[1],                        p_input->p_fmt->p_extra,                        p_input->p_fmt->i_extra );            }            p_bih->biWidth = p_input->p_fmt->video.i_width;            p_bih->biHeight= p_input->p_fmt->video.i_height;            p_bih->biPlanes= 1;            p_bih->biBitCount       = 24;            p_bih->biSizeImage      = 0;            p_bih->biXPelsPerMeter  = 0;            p_bih->biYPelsPerMeter  = 0;            p_bih->biClrUsed        = 0;            p_bih->biClrImportant   = 0;            switch( p_input->p_fmt->i_codec )            {                case VLC_FOURCC( 'm', 'p', '4', 'v' ):                    p_bih->biCompression = VLC_FOURCC( 'X', 'V', 'I', 'D' );                    break;                default:                    p_bih->biCompression = p_input->p_fmt->i_codec;                    break;            }#undef p_bih            break;        default:            return( VLC_EGENERIC );    }    p_stream->i_totalsize = 0;    p_stream->i_frames    = 0;    p_stream->i_duration  = 0;    /* fixed later */    p_stream->f_fps = 25;    p_stream->i_bitrate = 128 * 1024;    p_sys->i_streams++;    return( VLC_SUCCESS );}static int DelStream( sout_mux_t *p_mux, sout_input_t *p_input ){    msg_Dbg( p_mux, "removing input" );    free( p_input->p_sys );    return( 0 );}static int Mux      ( sout_mux_t *p_mux ){    sout_mux_sys_t  *p_sys = p_mux->p_sys;    avi_stream_t    *p_stream;    int i_stream;    int i;    if( p_sys->b_write_header )    {        block_t *p_hdr;        msg_Dbg( p_mux, "writing header" );        p_hdr = avi_HeaderCreateRIFF( p_mux );        sout_AccessOutWrite( p_mux->p_access, p_hdr );        p_sys->b_write_header = VLC_FALSE;    }    for( i = 0; i < p_mux->i_nb_inputs; i++ )    {        int i_count;        block_fifo_t *p_fifo;        i_stream = *((int*)p_mux->pp_inputs[i]->p_sys );        p_stream = &p_sys->stream[i_stream];        p_fifo = p_mux->pp_inputs[i]->p_fifo;

⌨️ 快捷键说明

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