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

📄 libavi.c

📁 VLC Player Source Code
💻 C
📖 第 1 页 / 共 3 页
字号:
/***************************************************************************** * libavi.c : LibAVI ***************************************************************************** * Copyright (C) 2001 the VideoLAN team * $Id: add60783b4edd5c1a7339f6c50dbe9ffff9745aa $ * 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., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. *****************************************************************************/#ifdef HAVE_CONFIG_H# include "config.h"#endif#include <vlc_common.h>#include <vlc_demux.h>#include <vlc_codecs.h>                                /* BITMAPINFOHEADER */#include "libavi.h"#define AVI_DEBUG 1#define __EVEN( x ) (((x) + 1) & ~1)static vlc_fourcc_t GetFOURCC( const uint8_t *p_buff ){    return VLC_FOURCC( p_buff[0], p_buff[1], p_buff[2], p_buff[3] );}#define AVI_ChunkFree( a, b ) _AVI_ChunkFree( (a), (avi_chunk_t*)(b) )void    _AVI_ChunkFree( stream_t *, avi_chunk_t *p_chk );/**************************************************************************** * * Basics functions to manipulates chunks * ****************************************************************************/static int AVI_ChunkReadCommon( stream_t *s, avi_chunk_t *p_chk ){    const uint8_t *p_peek;    int i_peek;    memset( p_chk, 0, sizeof( avi_chunk_t ) );    if( ( i_peek = stream_Peek( s, &p_peek, 8 ) ) < 8 )    {        return VLC_EGENERIC;    }    p_chk->common.i_chunk_fourcc = GetFOURCC( p_peek );    p_chk->common.i_chunk_size   = GetDWLE( p_peek + 4 );    p_chk->common.i_chunk_pos    = stream_Tell( s );    p_chk->common.p_father = NULL;    p_chk->common.p_next = NULL;    p_chk->common.p_first = NULL;    p_chk->common.p_next = NULL;#ifdef AVI_DEBUG    msg_Dbg( (vlc_object_t*)s,             "found Chunk fourcc:%8.8x (%4.4s) size:%"PRId64" pos:%"PRId64,             p_chk->common.i_chunk_fourcc,             (char*)&p_chk->common.i_chunk_fourcc,             p_chk->common.i_chunk_size,             p_chk->common.i_chunk_pos );#endif    return VLC_SUCCESS;}static int AVI_NextChunk( stream_t *s, avi_chunk_t *p_chk ){    avi_chunk_t chk;    if( !p_chk )    {        if( AVI_ChunkReadCommon( s, &chk ) )        {            return VLC_EGENERIC;        }        p_chk = &chk;    }    if( p_chk->common.p_father )    {        if( p_chk->common.p_father->common.i_chunk_pos +                __EVEN( p_chk->common.p_father->common.i_chunk_size ) + 8 <            p_chk->common.i_chunk_pos +                __EVEN( p_chk->common.i_chunk_size ) + 8 )        {            return VLC_EGENERIC;        }    }    return stream_Seek( s, p_chk->common.i_chunk_pos +                                 __EVEN( p_chk->common.i_chunk_size ) + 8 );}/**************************************************************************** * * Functions to read chunks * ****************************************************************************/static int AVI_ChunkRead_list( stream_t *s, avi_chunk_t *p_container ){    avi_chunk_t *p_chk;    const uint8_t *p_peek;    bool b_seekable;    if( p_container->common.i_chunk_size > 0 && p_container->common.i_chunk_size < 8 )    {        /* empty box */        msg_Warn( (vlc_object_t*)s, "empty list chunk" );        return VLC_EGENERIC;    }    if( stream_Peek( s, &p_peek, 12 ) < 12 )    {        msg_Warn( (vlc_object_t*)s, "cannot peek while reading list chunk" );        return VLC_EGENERIC;    }    stream_Control( s, STREAM_CAN_FASTSEEK, &b_seekable );    p_container->list.i_type = GetFOURCC( p_peek + 8 );    /* XXX fixed for on2 hack */    if( p_container->common.i_chunk_fourcc == AVIFOURCC_ON2 && p_container->list.i_type == AVIFOURCC_ON2f )    {        p_container->common.i_chunk_fourcc = AVIFOURCC_RIFF;        p_container->list.i_type = AVIFOURCC_AVI;    }    if( p_container->common.i_chunk_fourcc == AVIFOURCC_LIST &&        p_container->list.i_type == AVIFOURCC_movi )    {        msg_Dbg( (vlc_object_t*)s, "skipping movi chunk" );        if( b_seekable )        {            return AVI_NextChunk( s, p_container );        }        return VLC_SUCCESS; /* point at begining of LIST-movi */    }    if( stream_Read( s, NULL, 12 ) != 12 )    {        msg_Warn( (vlc_object_t*)s, "cannot enter chunk" );        return VLC_EGENERIC;    }#ifdef AVI_DEBUG    msg_Dbg( (vlc_object_t*)s,             "found LIST chunk: \'%4.4s\'",             (char*)&p_container->list.i_type );#endif    msg_Dbg( (vlc_object_t*)s, "<list \'%4.4s\'>", (char*)&p_container->list.i_type );    for( ; ; )    {        p_chk = malloc( sizeof( avi_chunk_t ) );        memset( p_chk, 0, sizeof( avi_chunk_t ) );        if( !p_container->common.p_first )        {            p_container->common.p_first = p_chk;        }        else        {            p_container->common.p_last->common.p_next = p_chk;        }        p_container->common.p_last = p_chk;        if( AVI_ChunkRead( s, p_chk, p_container ) )        {            break;        }        if( p_chk->common.p_father->common.i_chunk_size > 0 &&           ( stream_Tell( s ) >              (off_t)p_chk->common.p_father->common.i_chunk_pos +               (off_t)__EVEN( p_chk->common.p_father->common.i_chunk_size ) ) )        {            break;        }        /* If we can't seek then stop when we 've found LIST-movi */        if( p_chk->common.i_chunk_fourcc == AVIFOURCC_LIST &&            p_chk->list.i_type == AVIFOURCC_movi &&            ( !b_seekable || p_chk->common.i_chunk_size == 0 ) )        {            break;        }    }    msg_Dbg( (vlc_object_t*)s, "</list \'%4.4s\'>", (char*)&p_container->list.i_type );    return VLC_SUCCESS;}#define AVI_READCHUNK_ENTER \    int64_t i_read = __EVEN(p_chk->common.i_chunk_size ) + 8; \    uint8_t  *p_read, *p_buff;    \    if( !( p_read = p_buff = malloc(i_read ) ) ) \    { \        return VLC_EGENERIC; \    } \    i_read = stream_Read( s, p_read, i_read ); \    if( i_read < (int64_t)__EVEN(p_chk->common.i_chunk_size ) + 8 ) \    { \        free( p_buff ); \        return VLC_EGENERIC; \    }\    p_read += 8; \    i_read -= 8#define AVI_READ( res, func, size ) \    if( i_read < size ) { \        free( p_buff); \        return VLC_EGENERIC; \    } \    i_read -= size; \    res = func( p_read ); \    p_read += size \#define AVI_READCHUNK_EXIT( code ) \    free( p_buff ); \    return codestatic inline uint8_t GetB( uint8_t *ptr ){    return *ptr;}#define AVI_READ1BYTE( i_byte ) \    AVI_READ( i_byte, GetB, 1 )#define AVI_READ2BYTES( i_word ) \    AVI_READ( i_word, GetWLE, 2 )#define AVI_READ4BYTES( i_dword ) \    AVI_READ( i_dword, GetDWLE, 4 )#define AVI_READ8BYTES( i_qword ) \    AVI_READ( i_qword, GetQWLE, 8 )#define AVI_READFOURCC( i_dword ) \    AVI_READ( i_dword, GetFOURCC, 4 )static int AVI_ChunkRead_avih( stream_t *s, avi_chunk_t *p_chk ){    AVI_READCHUNK_ENTER;    p_chk->common.i_chunk_fourcc = AVIFOURCC_avih;    AVI_READ4BYTES( p_chk->avih.i_microsecperframe);    AVI_READ4BYTES( p_chk->avih.i_maxbytespersec );    AVI_READ4BYTES( p_chk->avih.i_reserved1 );    AVI_READ4BYTES( p_chk->avih.i_flags );    AVI_READ4BYTES( p_chk->avih.i_totalframes );    AVI_READ4BYTES( p_chk->avih.i_initialframes );    AVI_READ4BYTES( p_chk->avih.i_streams );    AVI_READ4BYTES( p_chk->avih.i_suggestedbuffersize );    AVI_READ4BYTES( p_chk->avih.i_width );    AVI_READ4BYTES( p_chk->avih.i_height );    AVI_READ4BYTES( p_chk->avih.i_scale );    AVI_READ4BYTES( p_chk->avih.i_rate );    AVI_READ4BYTES( p_chk->avih.i_start );    AVI_READ4BYTES( p_chk->avih.i_length );#ifdef AVI_DEBUG    msg_Dbg( (vlc_object_t*)s,             "avih: streams:%d flags:%s%s%s%s %dx%d",             p_chk->avih.i_streams,             p_chk->avih.i_flags&AVIF_HASINDEX?" HAS_INDEX":"",             p_chk->avih.i_flags&AVIF_MUSTUSEINDEX?" MUST_USE_INDEX":"",             p_chk->avih.i_flags&AVIF_ISINTERLEAVED?" IS_INTERLEAVED":"",             p_chk->avih.i_flags&AVIF_TRUSTCKTYPE?" TRUST_CKTYPE":"",             p_chk->avih.i_width, p_chk->avih.i_height );#endif    AVI_READCHUNK_EXIT( VLC_SUCCESS );}static int AVI_ChunkRead_strh( stream_t *s, avi_chunk_t *p_chk ){    AVI_READCHUNK_ENTER;    AVI_READFOURCC( p_chk->strh.i_type );    AVI_READFOURCC( p_chk->strh.i_handler );    AVI_READ4BYTES( p_chk->strh.i_flags );    AVI_READ4BYTES( p_chk->strh.i_reserved1 );    AVI_READ4BYTES( p_chk->strh.i_initialframes );    AVI_READ4BYTES( p_chk->strh.i_scale );    AVI_READ4BYTES( p_chk->strh.i_rate );    AVI_READ4BYTES( p_chk->strh.i_start );    AVI_READ4BYTES( p_chk->strh.i_length );    AVI_READ4BYTES( p_chk->strh.i_suggestedbuffersize );    AVI_READ4BYTES( p_chk->strh.i_quality );    AVI_READ4BYTES( p_chk->strh.i_samplesize );#ifdef AVI_DEBUG    msg_Dbg( (vlc_object_t*)s,             "strh: type:%4.4s handler:0x%8.8x samplesize:%d %.2ffps",             (char*)&p_chk->strh.i_type,             p_chk->strh.i_handler,             p_chk->strh.i_samplesize,             ( p_chk->strh.i_scale ?                (float)p_chk->strh.i_rate / (float)p_chk->strh.i_scale : -1) );#endif    AVI_READCHUNK_EXIT( VLC_SUCCESS );}static int AVI_ChunkRead_strf( stream_t *s, avi_chunk_t *p_chk ){

⌨️ 快捷键说明

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