Changeset b2b0749448fb79d6f68e6694f311306a62626d77

Show
Ignore:
Timestamp:
27/06/02 01:11:12 (6 years ago)
Author:
Laurent Aimar <fenrir@videolan.org>
git-committer:
Laurent Aimar <fenrir@videolan.org> 1025133072 +0000
git-parent:

[62e73f508b74167e0a9ceec13b155abb2f7aaaa0]

git-author:
Laurent Aimar <fenrir@videolan.org> 1025133072 +0000
Message:
  • all : I rewrite the way to read, in order to minimize seeking (

faster and in prevision of VOD by http, but not yet functionnal ). But
sound becomes horrible, I will try to fix it as soon as possible.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • plugins/avi/avi.c

    rb9e9cb4 rb2b0749  
    33 ***************************************************************************** 
    44 * Copyright (C) 2001 VideoLAN 
    5  * $Id: avi.c,v 1.22 2002/06/07 14:30:40 sam Exp $ 
     5 * $Id: avi.c,v 1.23 2002/06/26 23:11:12 fenrir Exp $ 
    66 * Authors: Laurent Aimar <fenrir@via.ecp.fr> 
    77 *  
     
    6767 * Definition of structures and libraries for this plugins  
    6868 *****************************************************************************/ 
    69 #include "libLE.c" 
    70 #include "libioRIFF.c" 
     69#include "libioRIFF.h" 
    7170#include "avi.h" 
    7271 
     
    8584} 
    8685 
    87 /********************************************************************/ 
     86 
     87/***************************************************************************** 
     88 * Some usefull functions to manipulate memory  
     89 *****************************************************************************/ 
     90static u16 GetWLE( byte_t *p_buff ) 
     91
     92    u16 i; 
     93    i = (*p_buff) + ( *(p_buff + 1) <<8 ); 
     94    return ( i ); 
     95
     96static u32 GetDWLE( byte_t *p_buff ) 
     97
     98    u32 i; 
     99    i = (*p_buff) + ( *(p_buff + 1) <<8 ) +  
     100            ( *(p_buff + 2) <<16 ) + ( *(p_buff + 3) <<24 ); 
     101    return ( i ); 
     102
     103static inline off_t __EVEN( off_t i ) 
     104
     105    return( (i & 1) ? i+1 : i ); 
     106
     107 
     108 
     109/***************************************************************************** 
     110 * Functions for parsing the headers in an avi file 
     111 *****************************************************************************/ 
     112static void AVI_Parse_avih( MainAVIHeader_t *p_avih, byte_t *p_buff ) 
     113
     114    p_avih->i_microsecperframe = GetDWLE( p_buff ); 
     115    p_avih->i_maxbytespersec   = GetDWLE( p_buff + 4); 
     116    p_avih->i_reserved1        = GetDWLE( p_buff + 8); 
     117    p_avih->i_flags            = GetDWLE( p_buff + 12); 
     118    p_avih->i_totalframes      = GetDWLE( p_buff + 16); 
     119    p_avih->i_initialframes    = GetDWLE( p_buff + 20); 
     120    p_avih->i_streams          = GetDWLE( p_buff + 24); 
     121    p_avih->i_suggestedbuffersize = GetDWLE( p_buff + 28); 
     122    p_avih->i_width            = GetDWLE( p_buff + 32 ); 
     123    p_avih->i_height           = GetDWLE( p_buff + 36 ); 
     124    p_avih->i_scale            = GetDWLE( p_buff + 40 ); 
     125    p_avih->i_rate             = GetDWLE( p_buff + 44 ); 
     126    p_avih->i_start            = GetDWLE( p_buff + 48); 
     127    p_avih->i_length           = GetDWLE( p_buff + 52); 
     128
     129static void AVI_Parse_Header( AVIStreamHeader_t *p_strh, byte_t *p_buff ) 
     130
     131    p_strh->i_type      = GetDWLE( p_buff ); 
     132    p_strh->i_handler   = GetDWLE( p_buff + 4 ); 
     133    p_strh->i_flags     = GetDWLE( p_buff + 8 ); 
     134    p_strh->i_reserved1 = GetDWLE( p_buff + 12); 
     135    p_strh->i_initialframes = GetDWLE( p_buff + 16); 
     136    p_strh->i_scale     = GetDWLE( p_buff + 20); 
     137    p_strh->i_rate      = GetDWLE( p_buff + 24); 
     138    p_strh->i_start     = GetDWLE( p_buff + 28); 
     139    p_strh->i_length    = GetDWLE( p_buff + 32); 
     140    p_strh->i_suggestedbuffersize = GetDWLE( p_buff + 36); 
     141    p_strh->i_quality   = GetDWLE( p_buff + 40); 
     142    p_strh->i_samplesize = GetDWLE( p_buff + 44); 
     143
     144static void AVI_Parse_BitMapInfoHeader( bitmapinfoheader_t *h, byte_t *p_data ) 
     145
     146    h->i_size          = GetDWLE( p_data ); 
     147    h->i_width         = GetDWLE( p_data + 4 ); 
     148    h->i_height        = GetDWLE( p_data + 8 ); 
     149    h->i_planes        = GetWLE( p_data + 12 ); 
     150    h->i_bitcount      = GetWLE( p_data + 14 ); 
     151    h->i_compression   = GetDWLE( p_data + 16 ); 
     152    h->i_sizeimage     = GetDWLE( p_data + 20 ); 
     153    h->i_xpelspermeter = GetDWLE( p_data + 24 ); 
     154    h->i_ypelspermeter = GetDWLE( p_data + 28 ); 
     155    h->i_clrused       = GetDWLE( p_data + 32 ); 
     156    h->i_clrimportant  = GetDWLE( p_data + 36 ); 
     157
     158static void AVI_Parse_WaveFormatEx( waveformatex_t *h, byte_t *p_data ) 
     159
     160    h->i_formattag     = GetWLE( p_data ); 
     161    h->i_channels      = GetWLE( p_data + 2 ); 
     162    h->i_samplespersec = GetDWLE( p_data + 4 ); 
     163    h->i_avgbytespersec= GetDWLE( p_data + 8 ); 
     164    h->i_blockalign    = GetWLE( p_data + 12 ); 
     165    h->i_bitspersample = GetWLE( p_data + 14 ); 
     166    h->i_size          = GetWLE( p_data + 16 ); 
     167
     168 
     169 
     170 
     171static inline int __AVI_GetESTypeFromTwoCC( u16 i_type ) 
     172
     173    switch( i_type ) 
     174    { 
     175        case( TWOCC_wb ): 
     176            return( AUDIO_ES ); 
     177         case( TWOCC_dc ): 
     178         case( TWOCC_db ): 
     179            return( VIDEO_ES ); 
     180    } 
     181    return( UNKNOWN_ES ); 
     182
     183 
     184static int AVI_AudioGetType( u32 i_type ) 
     185
     186    switch( i_type ) 
     187    { 
     188/*        case( WAVE_FORMAT_PCM ): 
     189            return( WAVE_AUDIO_ES ); */ 
     190        case( WAVE_FORMAT_AC3 ): 
     191            return( AC3_AUDIO_ES ); 
     192        case( WAVE_FORMAT_MPEG): 
     193        case( WAVE_FORMAT_MPEGLAYER3): 
     194            return( MPEG2_AUDIO_ES ); /* 2 for mpeg-2 layer 1 2 ou 3 */ 
     195        default: 
     196            return( 0 ); 
     197    } 
     198
     199static int AVI_VideoGetType( u32 i_type ) 
     200
     201    switch( i_type ) 
     202    { 
     203        case( FOURCC_DIV1 ): /* FIXME it is for msmpeg4v1 or old mpeg4 ?? */ 
     204        case( FOURCC_div1 ): 
     205        case( FOURCC_MPG4 ): 
     206        case( FOURCC_mpg4 ): 
     207            return( MSMPEG4v1_VIDEO_ES ); 
     208 
     209        case( FOURCC_DIV2 ): 
     210        case( FOURCC_div2 ): 
     211        case( FOURCC_MP42 ): 
     212        case( FOURCC_mp42 ): 
     213            return( MSMPEG4v2_VIDEO_ES ); 
     214          
     215        case( FOURCC_MPG3 ): 
     216        case( FOURCC_mpg3 ): 
     217        case( FOURCC_div3 ): 
     218        case( FOURCC_MP43 ): 
     219        case( FOURCC_mp43 ): 
     220        case( FOURCC_DIV3 ): 
     221        case( FOURCC_DIV4 ): 
     222        case( FOURCC_div4 ): 
     223        case( FOURCC_DIV5 ): 
     224        case( FOURCC_div5 ): 
     225        case( FOURCC_DIV6 ): 
     226        case( FOURCC_div6 ): 
     227        case( FOURCC_AP41 ): 
     228        case( FOURCC_3IV1 ): 
     229            return( MSMPEG4v3_VIDEO_ES ); 
     230 
     231 
     232        case( FOURCC_DIVX ): 
     233        case( FOURCC_divx ): 
     234        case( FOURCC_MP4S ): 
     235        case( FOURCC_mp4s ): 
     236        case( FOURCC_M4S2 ): 
     237        case( FOURCC_m4s2 ): 
     238        case( FOURCC_xvid ): 
     239        case( FOURCC_XVID ): 
     240        case( FOURCC_XviD ): 
     241        case( FOURCC_DX50 ): 
     242        case( FOURCC_mp4v ): 
     243        case( FOURCC_4    ): 
     244            return( MPEG4_VIDEO_ES ); 
     245 
     246        default: 
     247            return( 0 ); 
     248    } 
     249
     250/***************************************************************************** 
     251 * Data and functions to manipulate pes buffer 
     252 *****************************************************************************/ 
     253#define BUFFER_MAXTOTALSIZE   512*1024 /* 1/2 Mo */ 
     254#define BUFFER_MAXSPESSIZE 1024*200 
     255static void AVI_PESBuffer_Add( input_buffers_t *p_method_data, 
     256                               AVIStreamInfo_t *p_info, 
     257                               pes_packet_t *p_pes, 
     258                               int i_posc, 
     259                               int i_posb ) 
     260
     261    AVIESBuffer_t   *p_buffer_pes; 
     262 
     263    if( p_info->i_pes_totalsize > BUFFER_MAXTOTALSIZE ) 
     264    { 
     265        input_DeletePES( p_method_data, p_pes ); 
     266        return; 
     267    } 
     268     
     269    if( !( p_buffer_pes = malloc( sizeof( AVIESBuffer_t ) ) ) ) 
     270    { 
     271        input_DeletePES( p_method_data, p_pes ); 
     272        return; 
     273    } 
     274    p_buffer_pes->p_next = NULL; 
     275    p_buffer_pes->p_pes = p_pes; 
     276    p_buffer_pes->i_posc = i_posc; 
     277    p_buffer_pes->i_posb = i_posb; 
     278 
     279    if( p_info->p_pes_last )  
     280    { 
     281        p_info->p_pes_last->p_next = p_buffer_pes; 
     282    } 
     283    p_info->p_pes_last = p_buffer_pes; 
     284    if( !p_info->p_pes_first ) 
     285    { 
     286        p_info->p_pes_first = p_buffer_pes; 
     287    } 
     288    p_info->i_pes_count++; 
     289    p_info->i_pes_totalsize += p_pes->i_pes_size; 
     290
     291static pes_packet_t *AVI_PESBuffer_Get( AVIStreamInfo_t *p_info ) 
     292
     293    AVIESBuffer_t   *p_buffer_pes; 
     294    pes_packet_t    *p_pes; 
     295    if( p_info->p_pes_first ) 
     296    { 
     297        p_buffer_pes = p_info->p_pes_first; 
     298        p_info->p_pes_first = p_buffer_pes->p_next; 
     299        if( !p_info->p_pes_first ) 
     300        { 
     301            p_info->p_pes_last = NULL; 
     302        } 
     303        p_pes = p_buffer_pes->p_pes; 
     304 
     305        free( p_buffer_pes ); 
     306        p_info->i_pes_count--; 
     307        p_info->i_pes_totalsize -= p_pes->i_pes_size; 
     308        return( p_pes ); 
     309    } 
     310    else 
     311    { 
     312        return( NULL ); 
     313    } 
     314
     315static int AVI_PESBuffer_Drop( input_buffers_t *p_method_data, 
     316                                AVIStreamInfo_t *p_info ) 
     317
     318    pes_packet_t *p_pes = AVI_PESBuffer_Get( p_info ); 
     319    if( p_pes ) 
     320    { 
     321        input_DeletePES( p_method_data, p_pes ); 
     322        return( 1 ); 
     323    } 
     324    else 
     325    { 
     326        return( 0 ); 
     327    } 
     328
     329static void AVI_PESBuffer_Flush( input_buffers_t *p_method_data, 
     330                                 AVIStreamInfo_t *p_info ) 
     331
     332    while( p_info->p_pes_first ) 
     333    { 
     334        AVI_PESBuffer_Drop( p_method_data, p_info ); 
     335    } 
     336
     337 
     338 
     339 
     340 
     341 
     342 
     343 
    88344 
    89345 
     
    111367                { 
    112368                      free( p_avi_demux->pp_info[i]->p_index ); 
     369                      AVI_PESBuffer_Flush( p_input->p_method_data, p_avi_demux->pp_info[i] ); 
    113370                } 
    114371                free( p_avi_demux->pp_info[i] );  
     
    119376} 
    120377 
    121 static void __AVI_Parse_avih( MainAVIHeader_t *p_avih, byte_t *p_buff ) 
    122 
    123     p_avih->i_microsecperframe = __GetDoubleWordLittleEndianFromBuff( p_buff ); 
    124     p_avih->i_maxbytespersec = __GetDoubleWordLittleEndianFromBuff( p_buff + 4); 
    125     p_avih->i_reserved1 = __GetDoubleWordLittleEndianFromBuff( p_buff + 8); 
    126     p_avih->i_flags = __GetDoubleWordLittleEndianFromBuff( p_buff + 12); 
    127     p_avih->i_totalframes = __GetDoubleWordLittleEndianFromBuff( p_buff + 16); 
    128     p_avih->i_initialframes = __GetDoubleWordLittleEndianFromBuff( p_buff + 20); 
    129     p_avih->i_streams = __GetDoubleWordLittleEndianFromBuff( p_buff + 24); 
    130     p_avih->i_suggestedbuffersize =  
    131                         __GetDoubleWordLittleEndianFromBuff( p_buff + 28); 
    132     p_avih->i_width = __GetDoubleWordLittleEndianFromBuff( p_buff + 32 ); 
    133     p_avih->i_height = __GetDoubleWordLittleEndianFromBuff( p_buff + 36 ); 
    134     p_avih->i_scale = __GetDoubleWordLittleEndianFromBuff( p_buff + 40 ); 
    135     p_avih->i_rate = __GetDoubleWordLittleEndianFromBuff( p_buff + 44 ); 
    136     p_avih->i_start = __GetDoubleWordLittleEndianFromBuff( p_buff + 48); 
    137     p_avih->i_length = __GetDoubleWordLittleEndianFromBuff( p_buff + 52); 
    138 
    139  
    140 static void __AVI_Parse_Header( AVIStreamHeader_t *p_strh, byte_t *p_buff ) 
    141 
    142     p_strh->i_type = __GetDoubleWordLittleEndianFromBuff( p_buff ); 
    143     p_strh->i_handler = __GetDoubleWordLittleEndianFromBuff( p_buff + 4 ); 
    144     p_strh->i_flags = __GetDoubleWordLittleEndianFromBuff( p_buff + 8 ); 
    145     p_strh->i_reserved1 = __GetDoubleWordLittleEndianFromBuff( p_buff + 12); 
    146     p_strh->i_initialframes = __GetDoubleWordLittleEndianFromBuff( p_buff + 16); 
    147     p_strh->i_scale = __GetDoubleWordLittleEndianFromBuff( p_buff + 20); 
    148     p_strh->i_rate = __GetDoubleWordLittleEndianFromBuff( p_buff + 24); 
    149     p_strh->i_start = __GetDoubleWordLittleEndianFromBuff( p_buff + 28); 
    150     p_strh->i_length = __GetDoubleWordLittleEndianFromBuff( p_buff + 32); 
    151     p_strh->i_suggestedbuffersize =  
    152                         __GetDoubleWordLittleEndianFromBuff( p_buff + 36); 
    153     p_strh->i_quality = __GetDoubleWordLittleEndianFromBuff( p_buff + 40); 
    154     p_strh->i_samplesize = __GetDoubleWordLittleEndianFromBuff( p_buff + 44); 
    155 
    156  
    157 int avi_ParseBitMapInfoHeader( bitmapinfoheader_t *h, byte_t *p_data ) 
    158 
    159     h->i_size          = __GetDoubleWordLittleEndianFromBuff( p_data ); 
    160     h->i_width         = __GetDoubleWordLittleEndianFromBuff( p_data + 4 ); 
    161     h->i_height        = __GetDoubleWordLittleEndianFromBuff( p_data + 8 ); 
    162     h->i_planes        = __GetWordLittleEndianFromBuff( p_data + 12 ); 
    163     h->i_bitcount      = __GetWordLittleEndianFromBuff( p_data + 14 ); 
    164     h->i_compression   = __GetDoubleWordLittleEndianFromBuff( p_data + 16 ); 
    165     h->i_sizeimage     = __GetDoubleWordLittleEndianFromBuff( p_data + 20 ); 
    166     h->i_xpelspermeter = __GetDoubleWordLittleEndianFromBuff( p_data + 24 ); 
    167     h->i_ypelspermeter = __GetDoubleWordLittleEndianFromBuff( p_data + 28 ); 
    168     h->i_clrused       = __GetDoubleWordLittleEndianFromBuff( p_data + 32 ); 
    169     h->i_clrimportant  = __GetDoubleWordLittleEndianFromBuff( p_data + 36 ); 
    170     return( 0 ); 
    171 
    172  
    173 int avi_ParseWaveFormatEx( waveformatex_t *h, byte_t *p_data ) 
    174 
    175     h->i_formattag     = __GetWordLittleEndianFromBuff( p_data ); 
    176     h->i_channels      = __GetWordLittleEndianFromBuff( p_data + 2 ); 
    177     h->i_samplespersec = __GetDoubleWordLittleEndianFromBuff( p_data + 4 ); 
    178     h->i_avgbytespersec= __GetDoubleWordLittleEndianFromBuff( p_data + 8 ); 
    179     h->i_blockalign    = __GetWordLittleEndianFromBuff( p_data + 12 ); 
    180     h->i_bitspersample = __GetWordLittleEndianFromBuff( p_data + 14 ); 
    181     h->i_size          = __GetWordLittleEndianFromBuff( p_data + 16 ); 
    182     return( 0 ); 
    183 
    184  
    185 static inline int __AVIGetESTypeFromTwoCC( u16 i_type ) 
    186 
    187     switch( i_type ) 
    188     { 
    189         case( TWOCC_wb ): 
    190             return( AUDIO_ES ); 
    191          case( TWOCC_dc ): 
    192          case( TWOCC_db ): 
    193             return( VIDEO_ES ); 
    194     } 
    195     return( UNKNOWN_ES ); 
    196 
    197  
    198  
    199 static int __AVI_ParseStreamHeader( u32 i_id, int *i_number, u16 *i_type ) 
     378static void AVI_ParseStreamHeader( u32 i_id, int *i_number, int *i_type ) 
    200379{ 
    201380    int c1,c2,c3,c4; 
     
    208387    if( c1 < '0' || c1 > '9' || c2 < '0' || c2 > '9' ) 
    209388    { 
    210         return( -1 ); 
    211     } 
    212     *i_number = (c1 - '0') * 10 + (c2 - '0' ); 
    213     *i_type = ( c4 << 8) + c3; 
    214     return( 0 ); 
    215 }    
     389        *i_number = 100; /* > max stream number */ 
     390        *i_type = 0; 
     391    } 
     392    else 
     393    { 
     394        *i_number = (c1 - '0') * 10 + (c2 - '0' ); 
     395        *i_type = ( c4 << 8) + c3; 
     396    } 
     397
     398/* Function to manipulate stream easily */ 
     399static off_t AVI_TellAbsolute( input_thread_t *p_input ) 
     400
     401    off_t i_pos; 
     402    vlc_mutex_lock( &p_input->stream.stream_lock ); 
     403    i_pos= p_input->stream.p_selected_area->i_tell - 
     404            ( p_input->p_last_data - p_input->p_current_data  ); 
     405    vlc_mutex_unlock( &p_input->stream.stream_lock ); 
     406 
     407    return( i_pos ); 
     408
     409                             
     410static int AVI_SeekAbsolute( input_thread_t *p_input, 
     411                             off_t i_pos) 
     412
     413    off_t i_filepos; 
     414    /* FIXME add support for not seekable stream */ 
     415 
     416    i_filepos = AVI_TellAbsolute( p_input ); 
     417    if( i_pos != i_filepos ) 
     418    { 
     419        p_input->pf_seek( p_input, i_pos ); 
     420        input_AccessReinit( p_input ); 
     421    } 
     422    return( 1 ); 
     423
     424 
    216425 
    217426static void __AVI_AddEntryIndex( AVIStreamInfo_t *p_info, 
     
    233442                           p_info->i_idxmax *  
    234443                           sizeof( AVIIndexEntry_t ) ); 
    235         if( p_tmp == NULL )  
     444        if( !p_tmp )  
    236445        {  
    237446            p_info->i_idxmax -= 16384; 
     
    263472    int             i; 
    264473    int             i_number; 
    265     u16             i_type; 
     474    int             i_type; 
    266475    int             i_totalentry = 0; 
    267476    demux_data_avi_file_t *p_avi_demux = 
     
    293502            byte_t  *p_peek = p_buff + i * 16; 
    294503            i_totalentry++; 
    295             index.i_id = __GetDoubleWordLittleEndianFromBuff( p_peek ); 
    296             index.i_flags = __GetDoubleWordLittleEndianFromBuff( p_peek+4); 
    297             index.i_pos = __GetDoubleWordLittleEndianFromBuff( p_peek+8); 
    298             index.i_length = __GetDoubleWordLittleEndianFromBuff(p_peek+12); 
     504            index.i_id      = GetDWLE( p_peek ); 
     505            index.i_flags   = GetDWLE( p_peek+4); 
     506            index.i_pos     = GetDWLE( p_peek+8); 
     507            index.i_length  = GetDWLE(p_peek+12); 
     508            AVI_ParseStreamHeader( index.i_id, &i_number, &i_type ); 
    299509             
    300             if( (__AVI_ParseStreamHeader( index.i_id, &i_number, &i_type ) == 0) 
    301              &&(i_number <  p_avi_demux->i_streams ) 
    302              &&(p_avi_demux->pp_info[i_number]->i_cat ==  
    303                      __AVIGetESTypeFromTwoCC( i_type )))  
     510            if( ( i_number <  p_avi_demux->i_streams ) 
     511               &&(p_avi_demux->pp_info[i_number]->i_cat ==  
     512                     __AVI_GetESTypeFromTwoCC( i_type )))  
    304513            { 
    305514                __AVI_AddEntryIndex( p_avi_demux->pp_info[i_number], 
     
    311520 
    312521} 
    313 static int __AVI_SeekToChunk( input_thread_t *p_input, AVIStreamInfo_t *p_info ) 
    314 { 
    315     if( (p_info->p_index )&&(p_info->i_idxposc < p_info->i_idxnb) ) 
    316     { 
    317         p_input->pf_seek( p_input,  
    318                           (off_t)p_info->p_index[p_info->i_idxposc].i_pos); 
    319         input_AccessReinit( p_input ); 
    320         return( 0 ); 
    321     } 
    322     /* no index can't arrive but ...*/ 
    323     msg_Warn( p_input, "cannot seek"); 
    324     return( -1 ); 
    325 } 
    326  
    327522 
    328523/* XXX call after get p_movi */ 
     
    364559} 
    365560 
    366 static int __AVI_AudioGetType( u32 i_type ) 
    367 
    368     switch( i_type ) 
    369     { 
    370 /*        case( WAVE_FORMAT_PCM ): 
    371             return( WAVE_AUDIO_ES ); */ 
    372         case( WAVE_FORMAT_AC3 ): 
    373             return( AC3_AUDIO_ES ); 
    374         case( WAVE_FORMAT_MPEG): 
    375         case( WAVE_FORMAT_MPEGLAYER3): 
    376             return( MPEG2_AUDIO_ES ); /* 2 for mpeg-2 layer 1 2 ou 3 */ 
    377         default: 
    378             return( 0 ); 
    379     } 
    380 
    381  
    382 static int __AVI_VideoGetType( u32 i_type ) 
    383 
    384     switch( i_type ) 
    385     { 
    386 /* FIXME FIXME :  what are the correct tag for msmpeg4 v1 */ 
    387         case(  FOURCC_MPG4  ): 
    388         case(  FOURCC_mpg4  ): 
    389         case(  FOURCC_DIV2  ): 
    390         case(  FOURCC_div2  ): 
    391         case(  FOURCC_MP42  ): 
    392         case(  FOURCC_mp42  ): 
    393              return( MSMPEG4v2_VIDEO_ES ); 
    394             
    395         case(  FOURCC_MPG3  ): 
    396         case(  FOURCC_mpg3  ): 
    397         case(  FOURCC_div3  ): 
    398         case(  FOURCC_MP43  ): 
    399         case(  FOURCC_mp43  ): 
    400         case(  FOURCC_DIV3  ): 
    401         case(  FOURCC_DIV4  ): 
    402         case(  FOURCC_div4  ): 
    403         case(  FOURCC_DIV5  ): 
    404         case(  FOURCC_div5  ): 
    405         case(  FOURCC_DIV6  ): 
    406         case(  FOURCC_div6  ): 
    407         case(  FOURCC_AP41  ): 
    408         case(  FOURCC_3IV1  ): 
    409             return( MSMPEG4v3_VIDEO_ES ); 
    410  
    411  
    412         case(  FOURCC_DIVX  ): 
    413         case(  FOURCC_divx  ): 
    414         case(  FOURCC_DIV1  ): 
    415         case(  FOURCC_div1  ): 
    416         case(  FOURCC_MP4S  ): 
    417         case(  FOURCC_mp4s  ): 
    418         case(  FOURCC_M4S2  ): 
    419         case(  FOURCC_m4s2  ): 
    420         case(  FOURCC_xvid  ): 
    421         case(  FOURCC_XVID  ): 
    422         case(  FOURCC_XviD  ): 
    423         case(  FOURCC_DX50  ): 
    424         case(  FOURCC_mp4v  ): 
    425         case(  FOURCC_4     ): 
    426             return( MPEG4_VIDEO_ES ); 
    427  
    428         default: 
    429             return( 0 ); 
    430     } 
    431 
     561 
     562#if 0 
     563FILE *DumpAudio; 
     564#endif 
    432565 
    433566/***************************************************************************** 
     
    444577    int i; 
    445578 
    446     /* we need to seek to be able to readcorrectly */ 
    447     if( !p_input->stream.b_seekable )  
    448     { 
    449         msg_Warn( p_input, "RIFF-AVI module discarded (not seekable)" ); 
    450         return( -1 ); 
    451     } 
    452     p_input->p_demux_data =  
    453                 p_avi_demux = malloc( sizeof(demux_data_avi_file_t) ); 
    454     if( p_avi_demux == NULL ) 
     579    if( !( p_input->p_demux_data =  
     580                    p_avi_demux = malloc( sizeof(demux_data_avi_file_t) ) ) ) 
    455581    { 
    456582        msg_Err( p_input, "out of memory" ); 
     
    459585    memset( p_avi_demux, 0, sizeof( demux_data_avi_file_t ) ); 
    460586    p_avi_demux->i_rate = DEFAULT_RATE; 
    461     /* FIXME I don't know what it's do, copied from ESInit */ 
     587    p_avi_demux->b_seekable = ( ( p_input->stream.b_seekable ) 
     588                        &&( p_input->stream.i_method == INPUT_METHOD_FILE ) ); 
     589 
    462590    /* Initialize access plug-in structures. */ 
    463591    if( p_input->i_mtu == 0 ) 
     
    505633        return( -1 ); 
    506634    } 
    507     __AVI_Parse_avih( &p_avi_demux->avih, p_avih->p_data->p_payload_start ); 
     635    AVI_Parse_avih( &p_avi_demux->avih, p_avih->p_data->p_payload_start ); 
    508636    RIFF_DeleteChunk( p_input, p_avih ); 
    509637     
     
    568696            return( -1 ); 
    569697        } 
    570         __AVI_Parse_Header( &p_info->header, 
     698        AVI_Parse_Header( &p_info->header, 
    571699                            p_strh->p_data->p_payload_start); 
    572700        RIFF_DeleteChunk( p_input, p_strh );       
     
    603731            case( FOURCC_auds ): 
    604732                p_es->i_cat = AUDIO_ES; 
    605                 avi_ParseWaveFormatEx( &p_info->audio_format, 
     733                AVI_Parse_WaveFormatEx( &p_info->audio_format, 
    606734                                   p_strf->p_data->p_payload_start );  
    607735                p_es->b_audio = 1; 
    608736                p_es->i_type =  
    609                     __AVI_AudioGetType( p_info->audio_format.i_formattag ); 
    610                 if( p_es->i_type == 0
     737                    AVI_AudioGetType( p_info->audio_format.i_formattag ); 
     738                if( !p_es->i_type
    611739                { 
    612740                    msg_Err( p_input, "stream(%d,0x%x) not supported", i, 
     
    618746            case( FOURCC_vids ): 
    619747                p_es->i_cat = VIDEO_ES; 
    620                 avi_ParseBitMapInfoHeader( &p_info->video_format, 
     748                AVI_Parse_BitMapInfoHeader( &p_info->video_format, 
    621749                                   p_strf->p_data->p_payload_start );  
    622750                p_es->b_audio = 0; 
    623751                p_es->i_type =  
    624                     __AVI_VideoGetType( p_info->video_format.i_compression ); 
    625                 if( p_es->i_type == 0
     752                    AVI_VideoGetType( p_info->video_format.i_compression ); 
     753                if( !p_es->i_type
    626754                { 
    627755                    msg_Err( p_input, "stream(%d,%4.4s) not supported", i, 
     
    666794     
    667795    /* get index  XXX need to have p_movi */ 
    668     if( (p_avi_demux->avih.i_flags&AVIF_HASINDEX) != 0 ) 
     796    if( ( p_avi_demux->b_seekable ) 
     797        &&( p_avi_demux->avih.i_flags&AVIF_HASINDEX ) )  
    669798    { 
    670799        /* get index */ 
     
    672801        /* try to get i_idxoffset for each stream  */ 
    673802        __AVI_UpdateIndexOffset( p_input ); 
     803        /* to make sure to go the begining because unless demux will see a seek */ 
     804        RIFF_GoToChunk( p_input, p_avi_demux->p_movi ); 
     805        if( RIFF_DescendChunk( p_input ) != 0 ) 
     806        { 
     807            __AVIFreeDemuxData( p_input ); 
     808            msg_Err( p_input, "cannot go in (\"movi\")" ); 
     809            return( -1 ); 
     810        } 
    674811    } 
    675812    else 
     
    678815    } 
    679816 
    680      
    681     /* we verify that each stream have at least one entry or create it */ 
    682     for( i = 0; i < p_avi_demux->i_streams ; i++ ) 
    683     { 
    684         AVIIndexEntry_t index; 
    685         riffchunk_t     *p_chunk; 
    686 #define p_info  p_avi_demux->pp_info[i] 
    687         if( p_info->p_index == NULL ) 
    688         { 
    689             RIFF_GoToChunk( p_input, p_avi_demux->p_movi ); 
    690             if( RIFF_DescendChunk(p_input) != 0 ) { continue; } 
    691             p_chunk = NULL; 
    692             switch( p_info->i_cat )  
    693             { 
    694                 case( AUDIO_ES ): 
    695                     if( RIFF_FindChunk( p_input,  
    696                                VLC_FOURCC('0'+i/10, '0'+i%10,'w','b' ),  
    697                                              p_movi ) == 0) 
    698                     { 
    699                        p_chunk = RIFF_ReadChunk( p_input ); 
    700                     } 
    701                     break; 
    702                      
    703                 case( VIDEO_ES ): 
    704                     if( (RIFF_FindChunk( p_input,  
    705                                     VLC_FOURCC('0'+i/10, '0'+i%10,'d','c' ), 
    706                                             p_movi ) == 0) ) 
    707                     { 
    708                         p_chunk = RIFF_ReadChunk( p_input );  
    709                     } 
    710                     else 
    711                     { 
    712                         RIFF_GoToChunk( p_input, p_avi_demux->p_movi ); 
    713                         if( RIFF_DescendChunk(p_input) != 0 ) { continue; } 
    714                         if( (RIFF_FindChunk( p_input, 
    715                                         VLC_FOURCC('0'+i/10, '0'+i%10,'d','b' ), 
    716                                             p_movi ) == 0) ) 
    717                         { 
    718                             p_chunk = RIFF_ReadChunk( p_input ); 
    719                         } 
    720                     } 
    721                     break; 
    722             } 
    723             if( p_chunk != NULL ) 
    724             { 
    725                 index.i_id = p_chunk->i_id; 
    726                 index.i_flags = AVIIF_KEYFRAME; 
    727                 index.i_pos = p_chunk->i_pos; 
    728                 index.i_length = p_chunk->i_size; 
    729                 __AVI_AddEntryIndex( p_info, &index ); 
    730                 msg_Dbg( p_input, "add index entry (%4.4s) (%d)",  
    731                                   (char*)&p_chunk->i_id, i );  
    732                 
    733             } 
    734         } 
    735 #undef p_info 
    736     } 
    737  
    738     /* to make sure to go the begining because unless demux will see a seek */ 
    739     RIFF_GoToChunk( p_input, p_avi_demux->p_movi ); 
    740     if( RIFF_DescendChunk( p_input ) != 0 ) 
    741     { 
    742         __AVIFreeDemuxData( p_input ); 
    743         msg_Err( p_input, "cannot go in (\"movi\")" ); 
    744         return( -1 ); 
    745     } 
    746817 
    747818    /* print informations on streams */ 
    748     msg_Dbg( p_input, "AVIH: %d stream, flags %s%s%s%s%s%s ",  
     819    msg_Dbg( p_input, "AVIH: %d stream, flags %s%s%s%s ",  
    749820             p_avi_demux->i_streams, 
    750821             p_avi_demux->avih.i_flags&AVIF_HASINDEX?" HAS_INDEX":"", 
    751822             p_avi_demux->avih.i_flags&AVIF_MUSTUSEINDEX?" MUST_USE_INDEX":"", 
    752823             p_avi_demux->avih.i_flags&AVIF_ISINTERLEAVED?" IS_INTERLEAVED":"", 
    753              p_avi_demux->avih.i_flags&AVIF_TRUSTCKTYPE?" TRUST_CKTYPE":"", 
    754              p_avi_demux->avih.i_flags&AVIF_WASCAPTUREFILE?" CAPTUREFILE":"", 
    755              p_avi_demux->avih.i_flags&AVIF_COPYRIGHTED?" COPYRIGHTED":"" ); 
     824             p_avi_demux->avih.i_flags&AVIF_TRUSTCKTYPE?" TRUST_CKTYPE":"" ); 
    756825 
    757826    for( i = 0; i < p_avi_demux->i_streams; i++ ) 
     
    761830        { 
    762831            case( VIDEO_ES ): 
    763                 msg_Dbg( p_input, "video(%4.4s) %dx%d %dbpp %ffps (size %d)", 
     832                msg_Dbg( p_input, "video(%4.4s) %dx%d %dbpp %ffps", 
    764833                         (char*)&p_info->video_format.i_compression, 
    765834                         p_info->video_format.i_width, 
     
    767836                         p_info->video_format.i_bitcount, 
    768837                         (float)p_info->header.i_rate / 
    769                              (float)p_info->header.i_scale, 
    770                          p_info->header.i_samplesize ); 
     838                             (float)p_info->header.i_scale ); 
    771839                if( (p_avi_demux->p_info_video == NULL) )  
    772840                { 
    773841                    p_avi_demux->p_info_video = p_info; 
     842                    /* TODO add test to see if a decoder has been foud */ 
     843                    vlc_mutex_lock( &p_input->stream.stream_lock ); 
     844                    input_SelectES( p_input, p_info->p_es ); 
     845                    vlc_mutex_unlock( &p_input->stream.stream_lock ); 
    774846                } 
    775847                break; 
    776848 
    777849            case( AUDIO_ES ): 
    778                 msg_Dbg( p_input, "audio(0x%x) %d channels %dHz %dbits %ffps (size %d)", 
     850                msg_Dbg( p_input, "audio(0x%x) %d channels %dHz %dbits %d bytes", 
    779851                         p_info->audio_format.i_formattag, 
    780852                         p_info->audio_format.i_channels, 
    781853                         p_info->audio_format.i_samplespersec, 
    782854                         p_info->audio_format.i_bitspersample, 
    783                          (float)p_info->header.i_rate / 
    784                              (float)p_info->header.i_scale, 
    785855                         p_info->header.i_samplesize ); 
    786856                if( (p_avi_demux->p_info_audio == NULL) )  
    787857                { 
    788858                    p_avi_demux->p_info_audio = p_info; 
     859                    vlc_mutex_lock( &p_input->stream.stream_lock ); 
     860                    input_SelectES( p_input, p_info->p_es ); 
     861                    vlc_mutex_unlock( &p_input->stream.stream_lock ); 
    789862                } 
    790863                break; 
    791864            case( UNKNOWN_ES ): 
    792865                msg_Warn( p_input, "unhandled stream %d", i ); 
     866                break; 
    793867        } 
    794868#undef p_info     
    795869    } 
     870 
    796871 
    797872    /* we select the first audio and video ES */ 
    798873    vlc_mutex_lock( &p_input->stream.stream_lock ); 
    799     if( p_avi_demux->p_info_video != NULL )  
    800     { 
    801         input_SelectES( p_input, p_avi_demux->p_info_video->p_es ); 
    802         /*  it seems that it's useless to select es because there are selected  
    803          *  by the interface but i'm not sure of that */ 
    804     } 
    805     else 
    806     { 
    807         msg_Err( p_input, "no video stream found" ); 
    808     } 
    809  
    810     if( p_avi_demux->p_info_audio != NULL )  
    811     { 
    812         input_SelectES( p_input, p_avi_demux->p_info_audio->p_es ); 
    813     } 
    814     else 
     874    if( !p_avi_demux->p_info_video )  
     875    { 
     876        msg_Warn( p_input, "no video stream found" ); 
     877    } 
     878    if( !p_avi_demux->p_info_audio ) 
    815879    { 
    816880        msg_Warn( p_input, "no audio stream found!" ); 
     
    818882    p_input->stream.p_selected_program->b_is_ok = 1; 
    819883    vlc_mutex_unlock( &p_input->stream.stream_lock ); 
    820      
     884#if 0 
     885    DumpAudio = fopen( "tmp.mp3", "w+" ); 
     886#endif 
     887 
    821888    return( 0 ); 
    822889} 
     
    828895static void AVIEnd( input_thread_t *p_input ) 
    829896{    
     897#if 0 
     898    fclose( DumpAudio ); 
     899#endif 
    830900    __AVIFreeDemuxData( p_input );  
    831901    return; 
     
    833903 
    834904 
     905 
     906/***************************************************************************** 
     907 * Function to convert pts to chunk or byte 
     908 *****************************************************************************/ 
     909 
     910static inline mtime_t AVI_PTSToChunk( AVIStreamInfo_t *p_info,  
     911                                        mtime_t i_pts ) 
     912{ 
     913    return( (mtime_t)((double)i_pts * 
     914                      (double)p_info->header.i_rate / 
     915                      (double)p_info->header.i_scale / 
     916                      (double)1000000.0 ) ); 
     917} 
     918static inline mtime_t AVI_PTSToByte( AVIStreamInfo_t *p_info, 
     919                                       mtime_t i_pts ) 
     920{ 
     921    return( (mtime_t)((double)i_pts *  
     922                      (double)p_info->header.i_samplesize * 
     923                      (double)p_info->header.i_rate / 
     924                      (double)p_info->header.i_scale / 
     925                      (double)1000000.0 ) ); 
     926 
     927} 
    835928static mtime_t AVI_GetPTS( AVIStreamInfo_t *p_info ) 
    836929{ 
     
    856949 
    857950 
    858  
    859 static int __AVI_NextIndexEntry( input_thread_t *p_input,  
    860                                   AVIStreamInfo_t *p_info ) 
    861 { 
    862     AVIIndexEntry_t index; 
    863     riffchunk_t     *p_chunk; 
    864     AVIStreamInfo_t *p_info_tmp; 
    865     int             i; 
    866     int             i_idxposc; 
    867     int             b_inc = 0; 
    868     demux_data_avi_file_t *p_avi_demux = 
    869                         (demux_data_avi_file_t*)p_input->p_demux_data; 
    870  
    871     p_info->i_idxposc++; 
    872  
    873     if( p_info->i_idxposc < p_info->i_idxnb ) 
    874     { 
    875         return( 0 ); 
    876     } 
    877     if( p_info->i_idxposc > p_info->i_idxnb ) 
    878     { 
    879         return( -1 ); 
    880     } 
    881     p_info->i_idxposc--; 
    882      
    883     /* create entry on the fly */ 
    884     /* search for the more advance stream and parse from it for all streams*/ 
    885     p_info_tmp = p_info; 
    886     for( i = 0; i < p_avi_demux->i_streams; i++ ) 
    887     { 
    888 #define p_info_i p_avi_demux->pp_info[i] 
    889         if( ( p_info_i->p_index ) 
    890             && ( p_info_i->p_index[p_info_i->i_idxnb - 1].i_pos > 
    891             p_info_tmp->p_index[p_info_tmp->i_idxnb - 1].i_pos ) ) 
    892         { 
    893             p_info_tmp = p_info_i; 
    894         } 
    895 #undef  p_info_i 
    896     } 
    897         
    898     /* go to last defined entry */ 
    899     i_idxposc = p_info_tmp->i_idxposc; /* save p_info_tmp->i_idxposc */ 
    900     p_info_tmp->i_idxposc = p_info_tmp->i_idxnb - 1; 
    901     __AVI_SeekToChunk( p_input, p_info_tmp ); 
    902     p_info_tmp->i_idxposc = i_idxposc; 
    903  
    904     if( RIFF_NextChunk( p_input, p_avi_demux->p_movi ) != 0 ) 
    905     { 
    906         p_info->i_idxposc++; 
    907         return( -1 ); 
    908     } 
    909  
    910     /* save idxpos of p_info */ 
    911     /* now parse for all stream and stop when reach next chunk for p_info */ 
    912     for( i = 0; (i < 15)||(!b_inc); i++) 
    913     { 
    914         int i_number; 
    915         u16 i_type; 
    916         if( (p_chunk = RIFF_ReadChunk( p_input )) == NULL ) 
    917         { 
    918             p_info->i_idxposc++; 
    919             return( b_inc == 1 ? 0 : -1 ); 
    920         } 
    921  
    922         index.i_id = p_chunk->i_id; 
    923         index.i_flags = AVIIF_KEYFRAME; 
    924         index.i_pos = p_chunk->i_pos; 
    925         index.i_length = p_chunk->i_size; 
    926         RIFF_DeleteChunk( p_input, p_chunk ); 
    927 #define p_info_i    p_avi_demux->pp_info[i_number] 
    928        if( (__AVI_ParseStreamHeader( index.i_id, &i_number, &i_type ) == 0) 
    929              &&( i_number < p_avi_demux->i_streams ) 
    930              &&( p_info_i->p_index ) 
    931              &&( p_info_i->p_index[p_info_i->i_idxnb - 1].i_pos +  
    932                      p_info_i->p_index[p_info_i->i_idxnb - 1].i_length + 8<=  
    933                         index.i_pos )  
    934              &&( __AVIGetESTypeFromTwoCC( i_type ) == p_info_i->i_cat ) ) 
    935         { 
    936             __AVI_AddEntryIndex( p_info_i, &index ); 
    937             if( (p_info_i == p_info)&&(!b_inc) ) 
    938             { 
    939                 b_inc = 1; 
    940             } 
    941         } 
    942 #undef  p_info_i 
    943         if( RIFF_NextChunk( p_input, p_avi_demux->p_movi ) != 0 ) 
    944         { 
    945             p_info->i_idxposc++; 
    946             return( b_inc == 1 ? 0 : -1 ); 
    947         } 
    948  
    949     }  
    950  
    951     p_info->i_idxposc++; 
    952     return( 0 ); 
    953 } 
    954  
    955951/***************************************************************************** 
    956952 * Functions to acces streams data  
    957953 * Uses it, because i plane to read unseekable stream 
    958954 * Don't work for the moment for unseekable stream  
     955 * XXX NEVER set directly i_idxposc and i_idxposb 
    959956 *****************************************************************************/ 
    960957 
    961 /*      __AVI_ReadStreamChunkInPES;   load an entire chunk  
    962         __AVI_ReadStreamBytesInPES;   load bytes  
    963         __AVI_GoToStreamChunk;        go to chunk 
    964         __AVI_GoToStreamBytes;        go to bytes in the all stream   
    965  not seekable file is not yet supported 
    966  */ 
    967  
    968 static int __AVI_GoToStreamChunk( input_thread_t    *p_input,  
    969                                   AVIStreamInfo_t   *p_info, 
    970                                   int   i_chunk ) 
    971 
    972     u32   u32_pos; 
    973     off_t i_pos; 
     958/* FIXME FIXME change b_pad to number of bytes to skipp after reading */ 
     959static int __AVI_GetDataInPES( input_thread_t *p_input, 
     960                               pes_packet_t   **pp_pes, 
     961                               int i_size, 
     962                               int b_pad ) 
     963
     964 
     965    int i_read; 
     966    data_packet_t *p_data; 
    974967     
    975     if( !p_input->stream.b_seekable ) 
    976     { 
    977         msg_Err( p_input, "need the ability to seek in stream" ); 
    978       &