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

📄 avi.c

📁 video linux conference
💻 C
📖 第 1 页 / 共 2 页
字号:
        i_count = p_fifo->i_depth;        while( i_count > 1 )        {            avi_idx1_entry_t *p_idx;            block_t *p_data;            p_data = block_FifoGet( p_fifo );            if( p_fifo->i_depth > 0 )            {                block_t *p_next = block_FifoShow( p_fifo );                p_data->i_length = p_next->i_dts - p_data->i_dts;            }            p_stream->i_frames++;            if( p_data->i_length < 0 )            {                msg_Warn( p_mux, "argg length < 0 l" );                block_Release( p_data );                i_count--;                continue;            }            p_stream->i_duration  += p_data->i_length;            p_stream->i_totalsize += p_data->i_buffer;            /* add idx1 entry for this frame */            p_idx = &p_sys->idx1.entry[p_sys->idx1.i_entry_count];            memcpy( p_idx->fcc, p_stream->fcc, 4 );            p_idx->i_flags = AVIIF_KEYFRAME;            p_idx->i_pos   = p_sys->i_movi_size + 4;            p_idx->i_length= p_data->i_buffer;            p_sys->idx1.i_entry_count++;            if( p_sys->idx1.i_entry_count >= p_sys->idx1.i_entry_max )            {                p_sys->idx1.i_entry_max += 10000;                p_sys->idx1.entry = realloc( p_sys->idx1.entry,                                             p_sys->idx1.i_entry_max * sizeof( avi_idx1_entry_t ) );            }            p_data = block_Realloc( p_data, 8, p_data->i_buffer );            if( p_data )            {                SetFCC( p_data->p_buffer, p_stream->fcc );                SetDWLE( p_data->p_buffer + 4, p_data->i_buffer - 8 );                if( p_data->i_buffer & 0x01 )                {                    p_data = block_Realloc( p_data, 0, p_data->i_buffer + 1 );                }                p_sys->i_movi_size += p_data->i_buffer;                sout_AccessOutWrite( p_mux->p_access, p_data );            }            i_count--;        }    }    return( 0 );}/****************************************************************************//****************************************************************************//****************************************************************************//****************************************************************************/typedef struct buffer_out_s{    int      i_buffer_size;    int      i_buffer;    uint8_t  *p_buffer;} buffer_out_t;static void bo_Init( buffer_out_t *p_bo, int i_size, uint8_t *p_buffer ){    p_bo->i_buffer_size = i_size;    p_bo->i_buffer = 0;    p_bo->p_buffer = p_buffer;}static void bo_AddByte( buffer_out_t *p_bo, uint8_t i ){    if( p_bo->i_buffer < p_bo->i_buffer_size )    {        p_bo->p_buffer[p_bo->i_buffer] = i;    }    p_bo->i_buffer++;}static void bo_AddWordLE( buffer_out_t *p_bo, uint16_t i ){    bo_AddByte( p_bo, i &0xff );    bo_AddByte( p_bo, ( ( i >> 8) &0xff ) );}static void bo_AddWordBE( buffer_out_t *p_bo, uint16_t i ){    bo_AddByte( p_bo, ( ( i >> 8) &0xff ) );    bo_AddByte( p_bo, i &0xff );}static void bo_AddDWordLE( buffer_out_t *p_bo, uint32_t i ){    bo_AddWordLE( p_bo, i &0xffff );    bo_AddWordLE( p_bo, ( ( i >> 16) &0xffff ) );}static void bo_AddDWordBE( buffer_out_t *p_bo, uint32_t i ){    bo_AddWordBE( p_bo, ( ( i >> 16) &0xffff ) );    bo_AddWordBE( p_bo, i &0xffff );}#if 0static void bo_AddLWordLE( buffer_out_t *p_bo, uint64_t i ){    bo_AddDWordLE( p_bo, i &0xffffffff );    bo_AddDWordLE( p_bo, ( ( i >> 32) &0xffffffff ) );}static void bo_AddLWordBE( buffer_out_t *p_bo, uint64_t i ){    bo_AddDWordBE( p_bo, ( ( i >> 32) &0xffffffff ) );    bo_AddDWordBE( p_bo, i &0xffffffff );}#endifstatic void bo_AddFCC( buffer_out_t *p_bo, char *fcc ){    bo_AddByte( p_bo, fcc[0] );    bo_AddByte( p_bo, fcc[1] );    bo_AddByte( p_bo, fcc[2] );    bo_AddByte( p_bo, fcc[3] );}static void bo_AddMem( buffer_out_t *p_bo, int i_size, uint8_t *p_mem ){    int i;    for( i = 0; i < i_size; i++ )    {        bo_AddByte( p_bo, p_mem[i] );    }}/**************************************************************************** **************************************************************************** ** ** avi header generation ** **************************************************************************** ****************************************************************************/#define AVI_BOX_ENTER( fcc ) \    buffer_out_t _bo_sav_; \    bo_AddFCC( p_bo, fcc ); \    _bo_sav_ = *p_bo; \    bo_AddDWordLE( p_bo, 0 )#define AVI_BOX_ENTER_LIST( fcc ) \    AVI_BOX_ENTER( "LIST" ); \    bo_AddFCC( p_bo, fcc )#define AVI_BOX_EXIT( i_err ) \    if( p_bo->i_buffer&0x01 ) bo_AddByte( p_bo, 0 ); \    bo_AddDWordLE( &_bo_sav_, p_bo->i_buffer - _bo_sav_.i_buffer - 4 ); \    return( i_err );static int avi_HeaderAdd_avih( sout_mux_t *p_mux,                               buffer_out_t *p_bo ){    sout_mux_sys_t  *p_sys = p_mux->p_sys;    avi_stream_t    *p_video = NULL;    int         i_stream;    uint32_t    i_microsecperframe;    int         i_maxbytespersec;    int         i_totalframes;    AVI_BOX_ENTER( "avih" );    if( p_sys->i_stream_video >= 0 )    {        p_video = &p_sys->stream[p_sys->i_stream_video];        if( p_video->i_frames <= 0 )        {        //    p_video = NULL;        }    }    if( p_video )    {        i_microsecperframe =            (uint32_t)( (float)1000000 /                        (float)p_sys->stream[p_sys->i_stream_video].f_fps );        i_totalframes = p_sys->stream[p_sys->i_stream_video].i_frames;    }    else    {        msg_Warn( p_mux, "avi file without video track isn't a good idea..." );        i_microsecperframe = 0;        i_totalframes = 0;    }    for( i_stream = 0,i_maxbytespersec = 0; i_stream < p_sys->i_streams; i_stream++ )    {        if( p_sys->stream[i_stream].i_duration > 0 )        {            i_maxbytespersec +=                p_sys->stream[p_sys->i_stream_video].i_totalsize /                p_sys->stream[p_sys->i_stream_video].i_duration;        }    }    bo_AddDWordLE( p_bo, i_microsecperframe );    bo_AddDWordLE( p_bo, i_maxbytespersec );    bo_AddDWordLE( p_bo, 0 );                   /* padding */    bo_AddDWordLE( p_bo, AVIF_TRUSTCKTYPE |                         AVIF_HASINDEX |                         AVIF_ISINTERLEAVED );  /* flags */    bo_AddDWordLE( p_bo, i_totalframes );    bo_AddDWordLE( p_bo, 0 );                   /* initial frame */    bo_AddDWordLE( p_bo, p_sys->i_streams );    /* streams count */    bo_AddDWordLE( p_bo, 1024 * 1024 );         /* suggested buffer size */    if( p_video )    {        bo_AddDWordLE( p_bo, p_video->p_bih->biWidth );        bo_AddDWordLE( p_bo, p_video->p_bih->biHeight );    }    else    {        bo_AddDWordLE( p_bo, 0 );        bo_AddDWordLE( p_bo, 0 );    }    bo_AddDWordLE( p_bo, 0 );                   /* ???? */    bo_AddDWordLE( p_bo, 0 );                   /* ???? */    bo_AddDWordLE( p_bo, 0 );                   /* ???? */    bo_AddDWordLE( p_bo, 0 );                   /* ???? */    AVI_BOX_EXIT( 0 );}static int avi_HeaderAdd_strh( sout_mux_t   *p_mux,                               buffer_out_t *p_bo,                               avi_stream_t *p_stream ){    AVI_BOX_ENTER( "strh" );    switch( p_stream->i_cat )    {        case VIDEO_ES:            {                bo_AddFCC( p_bo, "vids" );                bo_AddDWordBE( p_bo, p_stream->p_bih->biCompression );                bo_AddDWordLE( p_bo, 0 );   /* flags */                bo_AddWordLE(  p_bo, 0 );   /* priority */                bo_AddWordLE(  p_bo, 0 );   /* langage */                bo_AddDWordLE( p_bo, 0 );   /* initial frame */                bo_AddDWordLE( p_bo, 1000 );/* scale */                bo_AddDWordLE( p_bo, (uint32_t)( 1000 * p_stream->f_fps ));                bo_AddDWordLE( p_bo, 0 );   /* start */                bo_AddDWordLE( p_bo, p_stream->i_frames );                bo_AddDWordLE( p_bo, 1024 * 1024 );                bo_AddDWordLE( p_bo, -1 );  /* quality */                bo_AddDWordLE( p_bo, 0 );   /* samplesize */                bo_AddWordLE(  p_bo, 0 );   /* ??? */                bo_AddWordLE(  p_bo, 0 );   /* ??? */                bo_AddWordLE(  p_bo, p_stream->p_bih->biWidth );                bo_AddWordLE(  p_bo, p_stream->p_bih->biHeight );            }            break;        case AUDIO_ES:            {                int i_rate, i_scale, i_samplesize;                i_samplesize = p_stream->p_wf->nBlockAlign;                if( i_samplesize > 1 )                {                    i_scale = i_samplesize;                    i_rate = /*i_scale **/ p_stream->i_bitrate / 8;                }                else                {                    i_samplesize = 1;                    i_scale = 1000;                    i_rate = 1000 * p_stream->i_bitrate / 8;                }                bo_AddFCC( p_bo, "auds" );                bo_AddDWordLE( p_bo, 0 );   /* tag */                bo_AddDWordLE( p_bo, 0 );   /* flags */                bo_AddWordLE(  p_bo, 0 );   /* priority */                bo_AddWordLE(  p_bo, 0 );   /* langage */                bo_AddDWordLE( p_bo, 0 );   /* initial frame */                bo_AddDWordLE( p_bo, i_scale );/* scale */                bo_AddDWordLE( p_bo, i_rate );                bo_AddDWordLE( p_bo, 0 );   /* start */                bo_AddDWordLE( p_bo, p_stream->i_frames );                bo_AddDWordLE( p_bo, 10 * 1024 );                bo_AddDWordLE( p_bo, -1 );  /* quality */                bo_AddDWordLE( p_bo, i_samplesize );                bo_AddWordLE(  p_bo, 0 );   /* ??? */                bo_AddWordLE(  p_bo, 0 );   /* ??? */                bo_AddWordLE(  p_bo, 0 );                bo_AddWordLE(  p_bo, 0 );            }            break;    }    AVI_BOX_EXIT( 0 );}static int avi_HeaderAdd_strf( sout_mux_t *p_mux,                               buffer_out_t *p_bo,                               avi_stream_t *p_stream ){    AVI_BOX_ENTER( "strf" );    switch( p_stream->i_cat )    {        case AUDIO_ES:            bo_AddWordLE( p_bo, p_stream->p_wf->wFormatTag );            bo_AddWordLE( p_bo, p_stream->p_wf->nChannels );            bo_AddDWordLE( p_bo, p_stream->p_wf->nSamplesPerSec );            bo_AddDWordLE( p_bo, p_stream->p_wf->nAvgBytesPerSec );            bo_AddWordLE( p_bo, p_stream->p_wf->nBlockAlign );            bo_AddWordLE( p_bo, p_stream->p_wf->wBitsPerSample );            bo_AddWordLE( p_bo, p_stream->p_wf->cbSize );            bo_AddMem( p_bo, p_stream->p_wf->cbSize, (uint8_t*)&p_stream->p_wf[1] );            break;        case VIDEO_ES:            bo_AddDWordLE( p_bo, p_stream->p_bih->biSize );            bo_AddDWordLE( p_bo, p_stream->p_bih->biWidth );            bo_AddDWordLE( p_bo, p_stream->p_bih->biHeight );            bo_AddWordLE( p_bo, p_stream->p_bih->biPlanes );            bo_AddWordLE( p_bo, p_stream->p_bih->biBitCount );            if( VLC_FOURCC( 0, 0, 0, 1 ) == 0x00000001 )            {                bo_AddDWordBE( p_bo, p_stream->p_bih->biCompression );            }            else            {                bo_AddDWordLE( p_bo, p_stream->p_bih->biCompression );            }            bo_AddDWordLE( p_bo, p_stream->p_bih->biSizeImage );            bo_AddDWordLE( p_bo, p_stream->p_bih->biXPelsPerMeter );            bo_AddDWordLE( p_bo, p_stream->p_bih->biYPelsPerMeter );            bo_AddDWordLE( p_bo, p_stream->p_bih->biClrUsed );            bo_AddDWordLE( p_bo, p_stream->p_bih->biClrImportant );            bo_AddMem( p_bo,                       p_stream->p_bih->biSize - sizeof( BITMAPINFOHEADER ),                       (uint8_t*)&p_stream->p_bih[1] );            break;    }    AVI_BOX_EXIT( 0 );}static int avi_HeaderAdd_strl( sout_mux_t *p_mux,                               buffer_out_t *p_bo,                               avi_stream_t *p_stream ){    AVI_BOX_ENTER_LIST( "strl" );    avi_HeaderAdd_strh( p_mux, p_bo, p_stream );    avi_HeaderAdd_strf( p_mux, p_bo, p_stream );    AVI_BOX_EXIT( 0 );}static block_t *avi_HeaderCreateRIFF( sout_mux_t *p_mux ){    sout_mux_sys_t      *p_sys = p_mux->p_sys;    block_t       *p_hdr;    int                 i_stream;    int                 i_maxbytespersec;    int                 i_junk;    buffer_out_t        bo;    p_hdr = block_New( p_mux, HDR_SIZE );    memset( p_hdr->p_buffer, 0, HDR_SIZE );    bo_Init( &bo, HDR_SIZE, p_hdr->p_buffer );    bo_AddFCC( &bo, "RIFF" );    bo_AddDWordLE( &bo, p_sys->i_movi_size + HDR_SIZE - 8 + p_sys->i_idx1_size );    bo_AddFCC( &bo, "AVI " );    bo_AddFCC( &bo, "LIST" );    bo_AddDWordLE( &bo, HDR_SIZE - 8);    bo_AddFCC( &bo, "hdrl" );    avi_HeaderAdd_avih( p_mux, &bo );    for( i_stream = 0,i_maxbytespersec = 0; i_stream < p_sys->i_streams; i_stream++ )    {        avi_HeaderAdd_strl( p_mux, &bo, &p_sys->stream[i_stream] );    }    i_junk = HDR_SIZE - bo.i_buffer - 8 - 12;    bo_AddFCC( &bo, "JUNK" );    bo_AddDWordLE( &bo, i_junk );    bo.i_buffer += i_junk;    bo_AddFCC( &bo, "LIST" );    bo_AddDWordLE( &bo, p_sys->i_movi_size + 4 );    bo_AddFCC( &bo, "movi" );    return( p_hdr );}static block_t * avi_HeaderCreateidx1( sout_mux_t *p_mux ){    sout_mux_sys_t      *p_sys = p_mux->p_sys;    block_t       *p_idx1;    uint32_t            i_idx1_size;    unsigned int        i;    buffer_out_t        bo;    i_idx1_size = 16 * p_sys->idx1.i_entry_count;    p_idx1 = block_New( p_mux, i_idx1_size + 8 );    memset( p_idx1->p_buffer, 0, i_idx1_size );    bo_Init( &bo, i_idx1_size, p_idx1->p_buffer );    bo_AddFCC( &bo, "idx1" );    bo_AddDWordLE( &bo, i_idx1_size );    for( i = 0; i < p_sys->idx1.i_entry_count; i++ )    {        bo_AddFCC( &bo, p_sys->idx1.entry[i].fcc );        bo_AddDWordLE( &bo, p_sys->idx1.entry[i].i_flags );        bo_AddDWordLE( &bo, p_sys->idx1.entry[i].i_pos );        bo_AddDWordLE( &bo, p_sys->idx1.entry[i].i_length );    }    return( p_idx1 );}

⌨️ 快捷键说明

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