avi.c
上传用户:riyaled888
上传日期:2009-03-27
资源大小:7338k
文件大小:72k
源码类别:

多媒体

开发平台:

MultiPlatform

  1. /*****************************************************************************
  2.  * avi.c : AVI file Stream input module for vlc
  3.  *****************************************************************************
  4.  * Copyright (C) 2001-2004 VideoLAN
  5.  * $Id: avi.c 9270 2004-11-10 13:05:27Z gbazin $
  6.  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  7.  *
  8.  * This program is free software; you can redistribute it and/or modify
  9.  * it under the terms of the GNU General Public License as published by
  10.  * the Free Software Foundation; either version 2 of the License, or
  11.  * (at your option) any later version.
  12.  *
  13.  * This program is distributed in the hope that it will be useful,
  14.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16.  * GNU General Public License for more details.
  17.  *
  18.  * You should have received a copy of the GNU General Public License
  19.  * along with this program; if not, write to the Free Software
  20.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
  21.  *****************************************************************************/
  22. /*****************************************************************************
  23.  * Preamble
  24.  *****************************************************************************/
  25. #include <stdlib.h>                                      /* malloc(), free() */
  26. #include <vlc/vlc.h>
  27. #include <vlc/input.h>
  28. #include "vlc_meta.h"
  29. #include "codecs.h"
  30. #include "libavi.h"
  31. /*****************************************************************************
  32.  * Module descriptor
  33.  *****************************************************************************/
  34. #define INTERLEAVE_TEXT N_("Force interleaved method" )
  35. #define INTERLEAVE_LONGTEXT N_( "Force interleaved method" )
  36. #define INDEX_TEXT N_("Force index creation")
  37. #define INDEX_LONGTEXT N_( 
  38.     "Recreate a index for the AVI file so we can seek trough it more reliably." )
  39. static int  Open ( vlc_object_t * );
  40. static void Close( vlc_object_t * );
  41. vlc_module_begin();
  42.     set_description( _("AVI demuxer") );
  43.     set_capability( "demux2", 212 );
  44.     add_bool( "avi-interleaved", 0, NULL,
  45.               INTERLEAVE_TEXT, INTERLEAVE_LONGTEXT, VLC_TRUE );
  46.     add_bool( "avi-index", 0, NULL,
  47.               INDEX_TEXT, INDEX_LONGTEXT, VLC_TRUE );
  48.     set_callbacks( Open, Close );
  49. vlc_module_end();
  50. /*****************************************************************************
  51.  * Local prototypes
  52.  *****************************************************************************/
  53. static int Control         ( demux_t *, int, va_list );
  54. static int Seek            ( demux_t *, mtime_t, int );
  55. static int Demux_Seekable  ( demux_t * );
  56. static int Demux_UnSeekable( demux_t * );
  57. #define FREE( p ) if( p ) { free( p ); (p) = NULL; }
  58. #define __ABS( x ) ( (x) < 0 ? (-(x)) : (x) )
  59. typedef struct
  60. {
  61.     vlc_fourcc_t i_fourcc;
  62.     off_t        i_pos;
  63.     uint32_t     i_size;
  64.     vlc_fourcc_t i_type;     /* only for AVIFOURCC_LIST */
  65.     uint8_t      i_peek[8];  /* first 8 bytes */
  66.     unsigned int i_stream;
  67.     unsigned int i_cat;
  68. } avi_packet_t;
  69. typedef struct
  70. {
  71.     vlc_fourcc_t i_id;
  72.     uint32_t     i_flags;
  73.     off_t        i_pos;
  74.     uint32_t     i_length;
  75.     uint32_t     i_lengthtotal;
  76. } avi_entry_t;
  77. typedef struct
  78. {
  79.     vlc_bool_t      b_activated;
  80.     unsigned int    i_cat; /* AUDIO_ES, VIDEO_ES */
  81.     vlc_fourcc_t    i_codec;
  82.     int             i_rate;
  83.     int             i_scale;
  84.     int             i_samplesize;
  85.     es_out_id_t     *p_es;
  86.     avi_entry_t     *p_index;
  87.     unsigned int        i_idxnb;
  88.     unsigned int        i_idxmax;
  89.     unsigned int        i_idxposc;  /* numero of chunk */
  90.     unsigned int        i_idxposb;  /* byte in the current chunk */
  91.     /* For VBR audio only */
  92.     unsigned int        i_blockno;
  93.     unsigned int        i_blocksize;
  94. } avi_track_t;
  95. struct demux_sys_t
  96. {
  97.     mtime_t i_time;
  98.     mtime_t i_length;
  99.     vlc_bool_t  b_seekable;
  100.     avi_chunk_t ck_root;
  101.     vlc_bool_t  b_odml;
  102.     off_t   i_movi_begin;
  103.     off_t   i_movi_lastchunk_pos;   /* XXX position of last valid chunk */
  104.     /* number of streams and information */
  105.     unsigned int i_track;
  106.     avi_track_t  **track;
  107.     /* meta */
  108.     vlc_meta_t  *meta;
  109. };
  110. static inline off_t __EVEN( off_t i )
  111. {
  112.     return (i & 1) ? i + 1 : i;
  113. }
  114. static mtime_t AVI_PTSToChunk( avi_track_t *, mtime_t i_pts );
  115. static mtime_t AVI_PTSToByte ( avi_track_t *, mtime_t i_pts );
  116. static mtime_t AVI_GetDPTS   ( avi_track_t *, int64_t i_count );
  117. static mtime_t AVI_GetPTS    ( avi_track_t * );
  118. static int AVI_StreamChunkFind( demux_t *, unsigned int i_stream );
  119. static int AVI_StreamChunkSet ( demux_t *,
  120.                                 unsigned int i_stream, unsigned int i_ck );
  121. static int AVI_StreamBytesSet ( demux_t *,
  122.                                 unsigned int i_stream, off_t   i_byte );
  123. vlc_fourcc_t AVI_FourccGetCodec( unsigned int i_cat, vlc_fourcc_t );
  124. static int   AVI_GetKeyFlag    ( vlc_fourcc_t , uint8_t * );
  125. static int AVI_PacketGetHeader( demux_t *, avi_packet_t *p_pk );
  126. static int AVI_PacketNext     ( demux_t * );
  127. static int AVI_PacketRead     ( demux_t *, avi_packet_t *, block_t **);
  128. static int AVI_PacketSearch   ( demux_t * );
  129. static void AVI_IndexLoad    ( demux_t * );
  130. static void AVI_IndexCreate  ( demux_t * );
  131. static void AVI_IndexAddEntry( demux_sys_t *, int, avi_entry_t * );
  132. static mtime_t  AVI_MovieGetLength( demux_t * );
  133. /*****************************************************************************
  134.  * Stream management
  135.  *****************************************************************************/
  136. static int        AVI_TrackSeek  ( demux_t *, int, mtime_t );
  137. static int        AVI_TrackStopFinishedStreams( demux_t *);
  138. /* Remarks:
  139.  - For VBR mp3 stream:
  140.     count blocks by rounded-up chunksizes instead of chunks
  141.     we need full emulation of dshow avi demuxer bugs :(
  142.     fixes silly nandub-style a-v delaying in avi with vbr mp3...
  143.     (from mplayer 2002/08/02)
  144.  - to complete....
  145.  */
  146. /*****************************************************************************
  147.  * Open: check file and initializes AVI structures
  148.  *****************************************************************************/
  149. static int Open( vlc_object_t * p_this )
  150. {
  151.     demux_t  *p_demux = (demux_t *)p_this;
  152.     demux_sys_t     *p_sys;
  153.     avi_chunk_t         ck_riff;
  154.     avi_chunk_list_t    *p_riff = (avi_chunk_list_t*)&ck_riff;
  155.     avi_chunk_list_t    *p_hdrl, *p_movi;
  156.     avi_chunk_avih_t    *p_avih;
  157.     unsigned int i_track;
  158.     unsigned int i, i_peeker;
  159.     uint8_t  *p_peek;
  160.     /* Is it an avi file ? */
  161.     if( stream_Peek( p_demux->s, &p_peek, 200 ) < 200 )
  162.     {
  163.         msg_Dbg( p_demux, "cannot peek()" );
  164.         return VLC_EGENERIC;
  165.     }
  166.     for( i_peeker = 0; i_peeker < 188; i_peeker++ )
  167.     {
  168.         if( !strncmp( &p_peek[0], "RIFF", 4 ) && !strncmp( &p_peek[8], "AVI ", 4 ) )
  169.         {
  170.             break;
  171.         }
  172.         p_peek++;
  173.     }
  174.     if( i_peeker == 188 )
  175.     {
  176.         msg_Warn( p_demux, "avi module discarded (invalid header)" );
  177.         return VLC_EGENERIC;
  178.     }
  179.     /* Initialize input  structures. */
  180.     p_sys = p_demux->p_sys = malloc( sizeof(demux_sys_t) );
  181.     memset( p_sys, 0, sizeof( demux_sys_t ) );
  182.     p_sys->i_time   = 0;
  183.     p_sys->i_length = 0;
  184.     p_sys->i_movi_lastchunk_pos = 0;
  185.     p_sys->b_odml   = VLC_FALSE;
  186.     p_sys->i_track  = 0;
  187.     p_sys->track    = NULL;
  188.     p_sys->meta     = NULL;
  189.     stream_Control( p_demux->s, STREAM_CAN_FASTSEEK, &p_sys->b_seekable );
  190.     p_demux->pf_control = Control;
  191.     p_demux->pf_demux = Demux_Seekable;
  192.     /* For unseekable stream, automaticaly use Demux_UnSeekable */
  193.     if( !p_sys->b_seekable || config_GetInt( p_demux, "avi-interleaved" ) )
  194.     {
  195.         p_demux->pf_demux = Demux_UnSeekable;
  196.     }
  197.     if( i_peeker > 0 )
  198.     {
  199. stream_Read( p_demux->s, NULL, i_peeker );
  200.     }
  201.     if( AVI_ChunkReadRoot( p_demux->s, &p_sys->ck_root ) )
  202.     {
  203.         msg_Err( p_demux, "avi module discarded (invalid file)" );
  204.         return VLC_EGENERIC;
  205.     }
  206.     if( AVI_ChunkCount( &p_sys->ck_root, AVIFOURCC_RIFF ) > 1 )
  207.     {
  208.         unsigned int i_count =
  209.             AVI_ChunkCount( &p_sys->ck_root, AVIFOURCC_RIFF );
  210.         msg_Warn( p_demux, "multiple riff -> OpenDML ?" );
  211.         for( i = 1; i < i_count; i++ )
  212.         {
  213.             avi_chunk_list_t *p_sysx;
  214.             p_sysx = AVI_ChunkFind( &p_sys->ck_root, AVIFOURCC_RIFF, i );
  215.             if( p_sysx->i_type == AVIFOURCC_AVIX )
  216.             {
  217.                 msg_Warn( p_demux, "detected OpenDML file" );
  218.                 p_sys->b_odml = VLC_TRUE;
  219.                 break;
  220.             }
  221.         }
  222.     }
  223.     p_riff  = AVI_ChunkFind( &p_sys->ck_root, AVIFOURCC_RIFF, 0 );
  224.     p_hdrl  = AVI_ChunkFind( p_riff, AVIFOURCC_hdrl, 0 );
  225.     p_movi  = AVI_ChunkFind( p_riff, AVIFOURCC_movi, 0 );
  226.     if( !p_hdrl || !p_movi )
  227.     {
  228.         msg_Err( p_demux, "avi module discarded (invalid file)" );
  229.         goto error;
  230.     }
  231.     if( !( p_avih = AVI_ChunkFind( p_hdrl, AVIFOURCC_avih, 0 ) ) )
  232.     {
  233.         msg_Err( p_demux, "cannot find avih chunk" );
  234.         goto error;
  235.     }
  236.     i_track = AVI_ChunkCount( p_hdrl, AVIFOURCC_strl );
  237.     if( p_avih->i_streams != i_track )
  238.     {
  239.         msg_Warn( p_demux,
  240.                   "found %d stream but %d are declared",
  241.                   i_track, p_avih->i_streams );
  242.     }
  243.     if( i_track == 0 )
  244.     {
  245.         msg_Err( p_demux, "no stream defined!" );
  246.         goto error;
  247.     }
  248.     /* print information on streams */
  249.     msg_Dbg( p_demux, "AVIH: %d stream, flags %s%s%s%s ",
  250.              i_track,
  251.              p_avih->i_flags&AVIF_HASINDEX?" HAS_INDEX":"",
  252.              p_avih->i_flags&AVIF_MUSTUSEINDEX?" MUST_USE_INDEX":"",
  253.              p_avih->i_flags&AVIF_ISINTERLEAVED?" IS_INTERLEAVED":"",
  254.              p_avih->i_flags&AVIF_TRUSTCKTYPE?" TRUST_CKTYPE":"" );
  255.     if( ( p_sys->meta = vlc_meta_New() ) )
  256.     {
  257.         char buffer[200];
  258.         sprintf( buffer, "%s%s%s%s",
  259.                  p_avih->i_flags&AVIF_HASINDEX?" HAS_INDEX":"",
  260.                  p_avih->i_flags&AVIF_MUSTUSEINDEX?" MUST_USE_INDEX":"",
  261.                  p_avih->i_flags&AVIF_ISINTERLEAVED?" IS_INTERLEAVED":"",
  262.                  p_avih->i_flags&AVIF_TRUSTCKTYPE?" TRUST_CKTYPE":"" );
  263.         vlc_meta_Add( p_sys->meta, VLC_META_SETTING, buffer );
  264.     }
  265.     /* now read info on each stream and create ES */
  266.     for( i = 0 ; i < i_track; i++ )
  267.     {
  268.         avi_track_t      *tk = malloc( sizeof( avi_track_t ) );
  269.         avi_chunk_list_t *p_strl = AVI_ChunkFind( p_hdrl, AVIFOURCC_strl, i );
  270.         avi_chunk_strh_t *p_strh = AVI_ChunkFind( p_strl, AVIFOURCC_strh, 0 );
  271.         avi_chunk_STRING_t *p_strn = AVI_ChunkFind( p_strl, AVIFOURCC_strn, 0 );
  272.         avi_chunk_strf_auds_t *p_auds;
  273.         avi_chunk_strf_vids_t *p_vids;
  274.         es_format_t fmt;
  275.         tk->b_activated = VLC_FALSE;
  276.         tk->p_index     = 0;
  277.         tk->i_idxnb     = 0;
  278.         tk->i_idxmax    = 0;
  279.         tk->i_idxposc   = 0;
  280.         tk->i_idxposb   = 0;
  281.         tk->i_blockno   = 0;
  282.         tk->i_blocksize = 0;
  283.         p_vids = (avi_chunk_strf_vids_t*)AVI_ChunkFind( p_strl, AVIFOURCC_strf, 0 );
  284.         p_auds = (avi_chunk_strf_auds_t*)AVI_ChunkFind( p_strl, AVIFOURCC_strf, 0 );
  285.         if( p_strl == NULL || p_strh == NULL || p_auds == NULL || p_vids == NULL )
  286.         {
  287.             msg_Warn( p_demux, "stream[%d] incomplete", i );
  288.             continue;
  289.         }
  290.         tk->i_rate  = p_strh->i_rate;
  291.         tk->i_scale = p_strh->i_scale;
  292.         tk->i_samplesize = p_strh->i_samplesize;
  293.         msg_Dbg( p_demux, "stream[%d] rate:%d scale:%d samplesize:%d",
  294.                  i, tk->i_rate, tk->i_scale, tk->i_samplesize );
  295.         switch( p_strh->i_type )
  296.         {
  297.             case( AVIFOURCC_auds ):
  298.                 tk->i_cat   = AUDIO_ES;
  299.                 tk->i_codec = AVI_FourccGetCodec( AUDIO_ES,
  300.                                                   p_auds->p_wf->wFormatTag );
  301.                 if( ( tk->i_blocksize = p_auds->p_wf->nBlockAlign ) == 0 )
  302.                 {
  303.                     if( p_auds->p_wf->wFormatTag == 1 )
  304.                     {
  305.                         tk->i_blocksize = p_auds->p_wf->nChannels * (p_auds->p_wf->wBitsPerSample/8);
  306.                     }
  307.                     else
  308.                     {
  309.                         tk->i_blocksize = 1;
  310.                     }
  311.                 }
  312.                 es_format_Init( &fmt, AUDIO_ES, tk->i_codec );
  313.                 fmt.audio.i_channels        = p_auds->p_wf->nChannels;
  314.                 fmt.audio.i_rate            = p_auds->p_wf->nSamplesPerSec;
  315.                 fmt.i_bitrate               = p_auds->p_wf->nAvgBytesPerSec*8;
  316.                 fmt.audio.i_blockalign      = p_auds->p_wf->nBlockAlign;
  317.                 fmt.audio.i_bitspersample   = p_auds->p_wf->wBitsPerSample;
  318.                 fmt.i_extra = __MIN( p_auds->p_wf->cbSize,
  319.                     p_auds->i_chunk_size - sizeof(WAVEFORMATEX) );
  320.                 fmt.p_extra = &p_auds->p_wf[1];
  321.                 msg_Dbg( p_demux, "stream[%d] audio(0x%x) %d channels %dHz %dbits",
  322.                          i, p_auds->p_wf->wFormatTag, p_auds->p_wf->nChannels,
  323.                          p_auds->p_wf->nSamplesPerSec, p_auds->p_wf->wBitsPerSample);
  324.                 break;
  325.             case( AVIFOURCC_vids ):
  326.                 tk->i_cat   = VIDEO_ES;
  327.                 tk->i_codec = AVI_FourccGetCodec( VIDEO_ES,
  328.                                                   p_vids->p_bih->biCompression );
  329.                 if( p_vids->p_bih->biCompression == 0x00 )
  330.                 {
  331.                     switch( p_vids->p_bih->biBitCount )
  332.                     {
  333.                         case 32:
  334.                             tk->i_codec = VLC_FOURCC('R','V','3','2');
  335.                             break;
  336.                         case 24:
  337.                             tk->i_codec = VLC_FOURCC('R','V','2','4');
  338.                             break;
  339.                         case 16:
  340.                             /* tk->i_codec = VLC_FOURCC('R','V','1','6');*/
  341.                             /* break;*/
  342.                         case 15:
  343.                             tk->i_codec = VLC_FOURCC('R','V','1','5');
  344.                             break;
  345.                         case 9:
  346.                             tk->i_codec = VLC_FOURCC( 'Y', 'V', 'U', '9' ); /* <- TODO check that */
  347.                             break;
  348.                     }
  349.                     es_format_Init( &fmt, VIDEO_ES, tk->i_codec );
  350.                     if( p_vids->p_bih->biBitCount == 24 )
  351.                     {
  352.                         /* This is in BGR format */
  353.                         fmt.video.i_bmask = 0x00ff0000;
  354.                         fmt.video.i_gmask = 0x0000ff00;
  355.                         fmt.video.i_rmask = 0x000000ff;
  356.                     }
  357.                 }
  358.                 else
  359.                 {
  360.                     es_format_Init( &fmt, VIDEO_ES, p_vids->p_bih->biCompression );
  361.                     if( tk->i_codec == FOURCC_mp4v &&
  362.                         !strncasecmp( (char*)&p_strh->i_handler, "XVID", 4 ) )
  363.                     {
  364.                         fmt.i_codec = VLC_FOURCC( 'X', 'V', 'I', 'D' );
  365.                     }
  366.                 }
  367.                 tk->i_samplesize = 0;
  368.                 fmt.video.i_width  = p_vids->p_bih->biWidth;
  369.                 fmt.video.i_height = p_vids->p_bih->biHeight;
  370.                 fmt.video.i_bits_per_pixel = p_vids->p_bih->biBitCount;
  371.                 fmt.i_extra =
  372.                     __MIN( p_vids->p_bih->biSize - sizeof( BITMAPINFOHEADER ),
  373.                            p_vids->i_chunk_size - sizeof(BITMAPINFOHEADER) );
  374.                 fmt.p_extra = &p_vids->p_bih[1];
  375.                 msg_Dbg( p_demux, "stream[%d] video(%4.4s) %dx%d %dbpp %ffps",
  376.                         i,
  377.                          (char*)&p_vids->p_bih->biCompression,
  378.                          p_vids->p_bih->biWidth,
  379.                          p_vids->p_bih->biHeight,
  380.                          p_vids->p_bih->biBitCount,
  381.                          (float)tk->i_rate/(float)tk->i_scale );
  382.                 if( p_vids->p_bih->biCompression == 0x00 )
  383.                 {
  384.                     /* RGB DIB are coded from bottom to top */
  385.                     fmt.video.i_height =
  386.                         (unsigned int)(-(int)p_vids->p_bih->biHeight);
  387.                 }
  388.                 break;
  389.             case( AVIFOURCC_txts):
  390.                 tk->i_cat   = SPU_ES;
  391.                 tk->i_codec = VLC_FOURCC( 's', 'u', 'b', 't' );
  392.                 msg_Dbg( p_demux, "stream[%d] subtitles", i );
  393.                 es_format_Init( &fmt, SPU_ES, tk->i_codec );
  394.                 break;
  395.                 
  396.             case( AVIFOURCC_mids):
  397.                 msg_Dbg( p_demux, "stream[%d] midi is UNSUPPORTED", i );
  398.             default:
  399.                 msg_Warn( p_demux, "stream[%d] unknown type", i );
  400.                 free( tk );
  401.                 continue;
  402.         }
  403.         if( p_strn )
  404.         {
  405.             fmt.psz_description = strdup( p_strn->p_str );
  406.         }
  407.         tk->p_es = es_out_Add( p_demux->out, &fmt );
  408.         TAB_APPEND( p_sys->i_track, p_sys->track, tk );
  409.     }
  410.     if( p_sys->i_track <= 0 )
  411.     {
  412.         msg_Err( p_demux, "no valid track" );
  413.         goto error;
  414.     }
  415.     if( config_GetInt( p_demux, "avi-index" ) )
  416.     {
  417.         if( p_sys->b_seekable )
  418.         {
  419.             AVI_IndexCreate( p_demux );
  420.         }
  421.         else
  422.         {
  423.             msg_Warn( p_demux, "cannot create index (unseekable stream)" );
  424.             AVI_IndexLoad( p_demux );
  425.         }
  426.     }
  427.     else
  428.     {
  429.         AVI_IndexLoad( p_demux );
  430.     }
  431.     /* *** movie length in sec *** */
  432.     p_sys->i_length = AVI_MovieGetLength( p_demux );
  433.     if( p_sys->i_length < (mtime_t)p_avih->i_totalframes *
  434.                           (mtime_t)p_avih->i_microsecperframe /
  435.                           (mtime_t)1000000 )
  436.     {
  437.         msg_Warn( p_demux, "broken or missing index, 'seek' will be axproximative or will have strange behavour" );
  438.     }
  439.     /* fix some BeOS MediaKit generated file */
  440.     for( i = 0 ; i < p_sys->i_track; i++ )
  441.     {
  442.         avi_track_t         *tk = p_sys->track[i];
  443.         avi_chunk_list_t    *p_strl;
  444.         avi_chunk_strh_t    *p_strh;
  445.         avi_chunk_strf_auds_t    *p_auds;
  446.         if( tk->i_cat != AUDIO_ES )
  447.         {
  448.             continue;
  449.         }
  450.         if( tk->i_idxnb < 1 ||
  451.             tk->i_scale != 1 ||
  452.             tk->i_samplesize != 0 )
  453.         {
  454.             continue;
  455.         }
  456.         p_strl = AVI_ChunkFind( p_hdrl, AVIFOURCC_strl, i );
  457.         p_strh = AVI_ChunkFind( p_strl, AVIFOURCC_strh, 0 );
  458.         p_auds = AVI_ChunkFind( p_strl, AVIFOURCC_strf, 0 );
  459.         if( p_auds->p_wf->wFormatTag != WAVE_FORMAT_PCM &&
  460.             (unsigned int)tk->i_rate == p_auds->p_wf->nSamplesPerSec )
  461.         {
  462.             int64_t i_track_length =
  463.                 tk->p_index[tk->i_idxnb-1].i_length +
  464.                 tk->p_index[tk->i_idxnb-1].i_lengthtotal;
  465.             mtime_t i_length = (mtime_t)p_avih->i_totalframes *
  466.                                (mtime_t)p_avih->i_microsecperframe;
  467.             if( i_length == 0 )
  468.             {
  469.                 msg_Warn( p_demux, "track[%d] cannot be fixed (BeOS MediaKit generated)", i );
  470.                 continue;
  471.             }
  472.             tk->i_samplesize = 1;
  473.             tk->i_rate       = i_track_length  * (int64_t)1000000/ i_length;
  474.             msg_Warn( p_demux, "track[%d] fixed with rate=%d scale=%d (BeOS MediaKit generated)", i, tk->i_rate, tk->i_scale );
  475.         }
  476.     }
  477.     if( p_sys->b_seekable )
  478.     {
  479.         /* we have read all chunk so go back to movi */
  480.         stream_Seek( p_demux->s, p_movi->i_chunk_pos );
  481.     }
  482.     /* Skip movi header */
  483.     stream_Read( p_demux->s, NULL, 12 );
  484.     p_sys->i_movi_begin = p_movi->i_chunk_pos;
  485.     return VLC_SUCCESS;
  486. error:
  487.     if( p_sys->meta )
  488.     {
  489.         vlc_meta_Delete( p_sys->meta );
  490.     }
  491.     AVI_ChunkFreeRoot( p_demux->s, &p_sys->ck_root );
  492.     free( p_sys );
  493.     return VLC_EGENERIC;
  494. }
  495. /*****************************************************************************
  496.  * Close: frees unused data
  497.  *****************************************************************************/
  498. static void Close ( vlc_object_t * p_this )
  499. {
  500.     demux_t *    p_demux = (demux_t *)p_this;
  501.     unsigned int i;
  502.     demux_sys_t *p_sys = p_demux->p_sys  ;
  503.     for( i = 0; i < p_sys->i_track; i++ )
  504.     {
  505.         if( p_sys->track[i] )
  506.         {
  507.             FREE( p_sys->track[i]->p_index );
  508.             free( p_sys->track[i] );
  509.         }
  510.     }
  511.     FREE( p_sys->track );
  512.     AVI_ChunkFreeRoot( p_demux->s, &p_sys->ck_root );
  513.     vlc_meta_Delete( p_sys->meta );
  514.     free( p_sys );
  515. }
  516. /*****************************************************************************
  517.  * Demux_Seekable: reads and demuxes data packets for stream seekable
  518.  *****************************************************************************
  519.  * AVIDemux: reads and demuxes data packets
  520.  *****************************************************************************
  521.  * Returns -1 in case of error, 0 in case of EOF, 1 otherwise
  522.  *****************************************************************************/
  523. typedef struct
  524. {
  525.     vlc_bool_t b_ok;
  526.     int i_toread;
  527.     off_t i_posf; /* where we will read :
  528.                    if i_idxposb == 0 : begining of chunk (+8 to acces data)
  529.                    else : point on data directly */
  530. } avi_track_toread_t;
  531. static int Demux_Seekable( demux_t *p_demux )
  532. {
  533.     demux_sys_t *p_sys = p_demux->p_sys;
  534.     unsigned int i_track_count = 0;
  535.     unsigned int i_track;
  536.     vlc_bool_t b_stream;
  537.     /* cannot be more than 100 stream (dcXX or wbXX) */
  538.     avi_track_toread_t toread[100];
  539.     /* detect new selected/unselected streams */
  540.     for( i_track = 0; i_track < p_sys->i_track; i_track++ )
  541.     {
  542.         avi_track_t *tk = p_sys->track[i_track];
  543.         vlc_bool_t  b;
  544.         es_out_Control( p_demux->out, ES_OUT_GET_ES_STATE, tk->p_es, &b );
  545.         if( b && !tk->b_activated )
  546.         {
  547.             if( p_sys->b_seekable)
  548.             {
  549.                 AVI_TrackSeek( p_demux, i_track, p_sys->i_time );
  550.             }
  551.             tk->b_activated = VLC_TRUE;
  552.         }
  553.         else if( !b && tk->b_activated )
  554.         {
  555.             tk->b_activated = VLC_FALSE;
  556.         }
  557.         if( b )
  558.         {
  559.             i_track_count++;
  560.         }
  561.     }
  562.     if( i_track_count <= 0 )
  563.     {
  564.         int64_t i_length = p_sys->i_length * (mtime_t)1000000;
  565.         p_sys->i_time += 25*1000;  /* read 25ms */
  566.         if( i_length > 0 )
  567.         {
  568.             if( p_sys->i_time >= i_length )
  569.                 return 0;
  570.             return 1;
  571.         }
  572.         msg_Warn( p_demux, "no track selected, exiting..." );
  573.         return 0;
  574.     }
  575.     /* wait for the good time */
  576.     es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_sys->i_time + 1 );
  577.     p_sys->i_time += 25*1000;  /* read 25ms */
  578.     /* init toread */
  579.     for( i_track = 0; i_track < p_sys->i_track; i_track++ )
  580.     {
  581.         avi_track_t *tk = p_sys->track[i_track];
  582.         mtime_t i_dpts;
  583.         toread[i_track].b_ok = tk->b_activated;
  584.         if( tk->i_idxposc < tk->i_idxnb )
  585.         {
  586.             toread[i_track].i_posf = tk->p_index[tk->i_idxposc].i_pos;
  587.            if( tk->i_idxposb > 0 )
  588.            {
  589.                 toread[i_track].i_posf += 8 + tk->i_idxposb;
  590.            }
  591.         }
  592.         else
  593.         {
  594.             toread[i_track].i_posf = -1;
  595.         }
  596.         i_dpts = p_sys->i_time - AVI_GetPTS( tk  );
  597.         if( tk->i_samplesize )
  598.         {
  599.             toread[i_track].i_toread = AVI_PTSToByte( tk, __ABS( i_dpts ) );
  600.         }
  601.         else
  602.         {
  603.             toread[i_track].i_toread = AVI_PTSToChunk( tk, __ABS( i_dpts ) );
  604.         }
  605.         if( i_dpts < 0 )
  606.         {
  607.             toread[i_track].i_toread *= -1;
  608.         }
  609.     }
  610.     b_stream = VLC_FALSE;
  611.     for( ;; )
  612.     {
  613.         avi_track_t     *tk;
  614.         vlc_bool_t       b_done;
  615.         block_t         *p_frame;
  616.         off_t i_pos;
  617.         unsigned int i;
  618.         size_t i_size;
  619.         /* search for first chunk to be read */
  620.         for( i = 0, b_done = VLC_TRUE, i_pos = -1; i < p_sys->i_track; i++ )
  621.         {
  622.             if( !toread[i].b_ok ||
  623.                 AVI_GetDPTS( p_sys->track[i],
  624.                              toread[i].i_toread ) <= -25 * 1000 )
  625.             {
  626.                 continue;
  627.             }
  628.             if( toread[i].i_toread > 0 )
  629.             {
  630.                 b_done = VLC_FALSE; /* not yet finished */
  631.             }
  632.             if( toread[i].i_posf > 0 )
  633.             {
  634.                 if( i_pos == -1 || i_pos > toread[i_track].i_posf )
  635.                 {
  636.                     i_track = i;
  637.                     i_pos = toread[i].i_posf;
  638.                 }
  639.             }
  640.         }
  641.         if( b_done )
  642.         {
  643.             return( 1 );
  644.         }
  645.         if( i_pos == -1 )
  646.         {
  647.             int i_loop_count = 0;
  648.             /* no valid index, we will parse directly the stream
  649.              * in case we fail we will disable all finished stream */
  650.             if( p_sys->i_movi_lastchunk_pos >= p_sys->i_movi_begin + 12 )
  651.             {
  652.                 stream_Seek( p_demux->s, p_sys->i_movi_lastchunk_pos );
  653.                 if( AVI_PacketNext( p_demux ) )
  654.                 {
  655.                     return( AVI_TrackStopFinishedStreams( p_demux ) ? 0 : 1 );
  656.                 }
  657.             }
  658.             else
  659.             {
  660.                 stream_Seek( p_demux->s, p_sys->i_movi_begin + 12 );
  661.             }
  662.             for( ;; )
  663.             {
  664.                 avi_packet_t avi_pk;
  665.                 if( AVI_PacketGetHeader( p_demux, &avi_pk ) )
  666.                 {
  667.                     msg_Warn( p_demux,
  668.                              "cannot get packet header, track disabled" );
  669.                     return( AVI_TrackStopFinishedStreams( p_demux ) ? 0 : 1 );
  670.                 }
  671.                 if( avi_pk.i_stream >= p_sys->i_track ||
  672.                     ( avi_pk.i_cat != AUDIO_ES && avi_pk.i_cat != VIDEO_ES ) )
  673.                 {
  674.                     if( AVI_PacketNext( p_demux ) )
  675.                     {
  676.                         msg_Warn( p_demux,
  677.                                   "cannot skip packet, track disabled" );
  678.                         return( AVI_TrackStopFinishedStreams( p_demux ) ? 0 : 1 );
  679.                     }
  680.                     /* Prevents from eating all the CPU with broken files.
  681.                      * This value should be low enough so that it doesn't
  682.                      * affect the reading speed too much. */
  683.                     if( !(++i_loop_count % 1024) )
  684.                     {
  685.                         if( p_demux->b_die ) return -1;
  686.                         msleep( 10000 );
  687.                         if( !(i_loop_count % (1024 * 10)) )
  688.                             msg_Warn( p_demux,
  689.                                       "don't seem to find any data..." );
  690.                     }
  691.                     continue;
  692.                 }
  693.                 else
  694.                 {
  695.                     /* add this chunk to the index */
  696.                     avi_entry_t index;
  697.                     index.i_id = avi_pk.i_fourcc;
  698.                     index.i_flags =
  699.                        AVI_GetKeyFlag(p_sys->track[avi_pk.i_stream]->i_codec,
  700.                                       avi_pk.i_peek);
  701.                     index.i_pos = avi_pk.i_pos;
  702.                     index.i_length = avi_pk.i_size;
  703.                     AVI_IndexAddEntry( p_sys, avi_pk.i_stream, &index );
  704.                     i_track = avi_pk.i_stream;
  705.                     tk = p_sys->track[i_track];
  706.                     /* do we will read this data ? */
  707.                     if( AVI_GetDPTS( tk, toread[i_track].i_toread ) > -25*1000 )
  708.                     {
  709.                         break;
  710.                     }
  711.                     else
  712.                     {
  713.                         if( AVI_PacketNext( p_demux ) )
  714.                         {
  715.                             msg_Warn( p_demux,
  716.                                       "cannot skip packet, track disabled" );
  717.                             return( AVI_TrackStopFinishedStreams( p_demux ) ? 0 : 1 );
  718.                         }
  719.                     }
  720.                 }
  721.             }
  722.         }
  723.         else
  724.         {
  725.             stream_Seek( p_demux->s, i_pos );
  726.         }
  727.         /* Set the track to use */
  728.         tk = p_sys->track[i_track];
  729.         /* read thoses data */
  730.         if( tk->i_samplesize )
  731.         {
  732.             unsigned int i_toread;
  733.             if( ( i_toread = toread[i_track].i_toread ) <= 0 )
  734.             {
  735.                 if( tk->i_samplesize > 1 )
  736.                 {
  737.                     i_toread = tk->i_samplesize;
  738.                 }
  739.                 else
  740.                 {
  741.                     i_toread = AVI_PTSToByte( tk, 20 * 1000 );
  742.                     i_toread = __MAX( i_toread, 100 );
  743.                 }
  744.             }
  745.             i_size = __MIN( tk->p_index[tk->i_idxposc].i_length -
  746.                                 tk->i_idxposb,
  747.                             i_toread );
  748.         }
  749.         else
  750.         {
  751.             i_size = tk->p_index[tk->i_idxposc].i_length;
  752.         }
  753.         if( tk->i_idxposb == 0 )
  754.         {
  755.             i_size += 8; /* need to read and skip header */
  756.         }
  757.         if( ( p_frame = stream_Block( p_demux->s, __EVEN( i_size ) ) )==NULL )
  758.         {
  759.             msg_Warn( p_demux, "failled reading data" );
  760.             tk->b_activated = VLC_FALSE;
  761.             toread[i_track].b_ok = VLC_FALSE;
  762.             continue;
  763.         }
  764.         if( i_size % 2 )    /* read was padded on word boundary */
  765.         {
  766.             p_frame->i_buffer--;
  767.         }
  768.         /* skip header */
  769.         if( tk->i_idxposb == 0 )
  770.         {
  771.             p_frame->p_buffer += 8;
  772.             p_frame->i_buffer -= 8;
  773.         }
  774.         p_frame->i_pts = AVI_GetPTS( tk ) + 1;
  775.         if( tk->p_index[tk->i_idxposc].i_flags&AVIIF_KEYFRAME )
  776.         {
  777.             p_frame->i_flags = BLOCK_FLAG_TYPE_I;
  778.         }
  779.         else
  780.         {
  781.             p_frame->i_flags = BLOCK_FLAG_TYPE_PB;
  782.         }
  783.         /* read data */
  784.         if( tk->i_samplesize )
  785.         {
  786.             if( tk->i_idxposb == 0 )
  787.             {
  788.                 i_size -= 8;
  789.             }
  790.             toread[i_track].i_toread -= i_size;
  791.             tk->i_idxposb += i_size;
  792.             if( tk->i_idxposb >=
  793.                     tk->p_index[tk->i_idxposc].i_length )
  794.             {
  795.                 tk->i_idxposb = 0;
  796.                 tk->i_idxposc++;
  797.             }
  798.         }
  799.         else
  800.         {
  801.             int i_length = tk->p_index[tk->i_idxposc].i_length;
  802.             tk->i_idxposc++;
  803.             if( tk->i_cat == AUDIO_ES )
  804.             {
  805.                 tk->i_blockno += tk->i_blocksize > 0 ? ( i_length + tk->i_blocksize - 1 ) / tk->i_blocksize : 1;
  806.             }
  807.             toread[i_track].i_toread--;
  808.         }
  809.         if( tk->i_idxposc < tk->i_idxnb)
  810.         {
  811.             toread[i_track].i_posf =
  812.                 tk->p_index[tk->i_idxposc].i_pos;
  813.             if( tk->i_idxposb > 0 )
  814.             {
  815.                 toread[i_track].i_posf += 8 + tk->i_idxposb;
  816.             }
  817.         }
  818.         else
  819.         {
  820.             toread[i_track].i_posf = -1;
  821.         }
  822.         b_stream = VLC_TRUE; /* at least one read succeed */
  823.         if( tk->i_cat != VIDEO_ES )
  824.             p_frame->i_dts = p_frame->i_pts;
  825.         else
  826.         {
  827.             p_frame->i_dts = p_frame->i_pts;
  828.             p_frame->i_pts = 0;
  829.         }
  830.         //p_pes->i_rate = p_demux->stream.control.i_rate;
  831.         es_out_Send( p_demux->out, tk->p_es, p_frame );
  832.     }
  833. }
  834. /*****************************************************************************
  835.  * Demux_UnSeekable: reads and demuxes data packets for unseekable file
  836.  *****************************************************************************
  837.  * Returns -1 in case of error, 0 in case of EOF, 1 otherwise
  838.  *****************************************************************************/
  839. static int Demux_UnSeekable( demux_t *p_demux )
  840. {
  841.     demux_sys_t     *p_sys = p_demux->p_sys;
  842.     avi_track_t *p_stream_master = NULL;
  843.     unsigned int i_stream;
  844.     unsigned int i_packet;
  845.     es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_sys->i_time + 1 );
  846.     /* *** find master stream for data packet skipping algo *** */
  847.     /* *** -> first video, if any, or first audio ES *** */
  848.     for( i_stream = 0; i_stream < p_sys->i_track; i_stream++ )
  849.     {
  850.         avi_track_t *tk = p_sys->track[i_stream];
  851.         vlc_bool_t  b;
  852.         es_out_Control( p_demux->out, ES_OUT_GET_ES_STATE, tk->p_es, &b );
  853.         if( b && tk->i_cat == VIDEO_ES )
  854.         {
  855.             p_stream_master = tk;
  856.         }
  857.         else if( b )
  858.         {
  859.             p_stream_master = tk;
  860.         }
  861.     }
  862.     if( !p_stream_master )
  863.     {
  864.         msg_Warn( p_demux, "no more stream selected" );
  865.         return( 0 );
  866.     }
  867.     p_sys->i_time = AVI_GetPTS( p_stream_master );
  868.     for( i_packet = 0; i_packet < 10; i_packet++)
  869.     {
  870. #define p_stream    p_sys->track[avi_pk.i_stream]
  871.         avi_packet_t    avi_pk;
  872.         if( AVI_PacketGetHeader( p_demux, &avi_pk ) )
  873.         {
  874.             return( 0 );
  875.         }
  876.         if( avi_pk.i_stream >= p_sys->i_track ||
  877.             ( avi_pk.i_cat != AUDIO_ES && avi_pk.i_cat != VIDEO_ES ) )
  878.         {
  879.             /* we haven't found an audio or video packet:
  880.              *  - we have seek, found first next packet
  881.              *  - others packets could be found, skip them
  882.              */
  883.             switch( avi_pk.i_fourcc )
  884.             {
  885.                 case AVIFOURCC_JUNK:
  886.                 case AVIFOURCC_LIST:
  887.                 case AVIFOURCC_RIFF:
  888.                     return( !AVI_PacketNext( p_demux ) ? 1 : 0 );
  889.                 case AVIFOURCC_idx1:
  890.                     if( p_sys->b_odml )
  891.                     {
  892.                         return( !AVI_PacketNext( p_demux ) ? 1 : 0 );
  893.                     }
  894.                     return( 0 );    /* eof */
  895.                 default:
  896.                     msg_Warn( p_demux,
  897.                               "seems to have lost position, resync" );
  898.                     if( AVI_PacketSearch( p_demux ) )
  899.                     {
  900.                         msg_Err( p_demux, "resync failed" );
  901.                         return( -1 );
  902.                     }
  903.             }
  904.         }
  905.         else
  906.         {
  907.             /* check for time */
  908.             if( __ABS( AVI_GetPTS( p_stream ) -
  909.                         AVI_GetPTS( p_stream_master ) )< 600*1000 )
  910.             {
  911.                 /* load it and send to decoder */
  912.                 block_t *p_frame;
  913.                 if( AVI_PacketRead( p_demux, &avi_pk, &p_frame ) || p_frame == NULL )
  914.                 {
  915.                     return( -1 );
  916.                 }
  917.                 p_frame->i_pts = AVI_GetPTS( p_stream ) + 1;
  918.                 if( avi_pk.i_cat != VIDEO_ES )
  919.                     p_frame->i_dts = p_frame->i_pts;
  920.                 else
  921.                 {
  922.                     p_frame->i_dts = p_frame->i_pts;
  923.                     p_frame->i_pts = 0;
  924.                 }
  925.                 //p_pes->i_rate = p_demux->stream.control.i_rate;
  926.                 es_out_Send( p_demux->out, p_stream->p_es, p_frame );
  927.             }
  928.             else
  929.             {
  930.                 if( AVI_PacketNext( p_demux ) )
  931.                 {
  932.                     return( 0 );
  933.                 }
  934.             }
  935.             /* *** update stream time position *** */
  936.             if( p_stream->i_samplesize )
  937.             {
  938.                 p_stream->i_idxposb += avi_pk.i_size;
  939.             }
  940.             else
  941.             {
  942.                 if( p_stream->i_cat == AUDIO_ES )
  943.                 {
  944.                     p_stream->i_blockno += p_stream->i_blocksize > 0 ? ( avi_pk.i_size + p_stream->i_blocksize - 1 ) / p_stream->i_blocksize : 1;
  945.                 }
  946.                 p_stream->i_idxposc++;
  947.             }
  948.         }
  949. #undef p_stream
  950.     }
  951.     return( 1 );
  952. }
  953. /*****************************************************************************
  954.  * Seek: goto to i_date or i_percent
  955.  *****************************************************************************/
  956. static int Seek( demux_t *p_demux, mtime_t i_date, int i_percent )
  957. {
  958.     demux_sys_t *p_sys = p_demux->p_sys;
  959.     unsigned int i_stream;
  960.     msg_Dbg( p_demux, "seek requested: "I64Fd" secondes %d%%",
  961.              i_date / 1000000, i_percent );
  962.     if( p_sys->b_seekable )
  963.     {
  964.         if( !p_sys->i_length )
  965.         {
  966.             avi_track_t *p_stream;
  967.             int64_t i_pos;
  968.             /* use i_percent to create a true i_date */
  969.             msg_Warn( p_demux, "mmh, seeking without index at %d%%"
  970.                       " work only for interleaved file", i_percent );
  971.             if( i_percent >= 100 )
  972.             {
  973.                 msg_Warn( p_demux, "cannot seek so far !" );
  974.                 return VLC_EGENERIC;
  975.             }
  976.             i_percent = __MAX( i_percent, 0 );
  977.             /* try to find chunk that is at i_percent or the file */
  978.             i_pos = __MAX( i_percent * stream_Size( p_demux->s ) / 100,
  979.                            p_sys->i_movi_begin );
  980.             /* search first selected stream */
  981.             for( i_stream = 0, p_stream = NULL;
  982.                         i_stream < p_sys->i_track; i_stream++ )
  983.             {
  984.                 p_stream = p_sys->track[i_stream];
  985.                 if( p_stream->b_activated )
  986.                 {
  987.                     break;
  988.                 }
  989.             }
  990.             if( !p_stream || !p_stream->b_activated )
  991.             {
  992.                 msg_Warn( p_demux, "cannot find any selected stream" );
  993.                 return VLC_EGENERIC;
  994.             }
  995.             /* be sure that the index exist */
  996.             if( AVI_StreamChunkSet( p_demux, i_stream, 0 ) )
  997.             {
  998.                 msg_Warn( p_demux, "cannot seek" );
  999.                 return VLC_EGENERIC;
  1000.             }
  1001.             while( i_pos >= p_stream->p_index[p_stream->i_idxposc].i_pos +
  1002.                p_stream->p_index[p_stream->i_idxposc].i_length + 8 )
  1003.             {
  1004.                 /* search after i_idxposc */
  1005.                 if( AVI_StreamChunkSet( p_demux,
  1006.                                         i_stream, p_stream->i_idxposc + 1 ) )
  1007.                 {
  1008.                     msg_Warn( p_demux, "cannot seek" );
  1009.                     return VLC_EGENERIC;
  1010.                 }
  1011.             }
  1012.             i_date = AVI_GetPTS( p_stream );
  1013.             /* TODO better support for i_samplesize != 0 */
  1014.             msg_Dbg( p_demux, "estimate date "I64Fd, i_date );
  1015.         }
  1016. #define p_stream    p_sys->track[i_stream]
  1017.         p_sys->i_time = 0;
  1018.         /* seek for chunk based streams */
  1019.         for( i_stream = 0; i_stream < p_sys->i_track; i_stream++ )
  1020.         {
  1021.             if( p_stream->b_activated && !p_stream->i_samplesize )
  1022. /*            if( p_stream->b_activated ) */
  1023.             {
  1024.                 AVI_TrackSeek( p_demux, i_stream, i_date );
  1025.                 p_sys->i_time = __MAX( AVI_GetPTS( p_stream ),
  1026.                                         p_sys->i_time );
  1027.             }
  1028.         }
  1029. #if 1
  1030.         if( p_sys->i_time )
  1031.         {
  1032.             i_date = p_sys->i_time;
  1033.         }
  1034.         /* seek for bytes based streams */
  1035.         for( i_stream = 0; i_stream < p_sys->i_track; i_stream++ )
  1036.         {
  1037.             if( p_stream->b_activated && p_stream->i_samplesize )
  1038.             {
  1039.                 AVI_TrackSeek( p_demux, i_stream, i_date );
  1040. /*                p_sys->i_time = __MAX( AVI_GetPTS( p_stream ), p_sys->i_time );*/
  1041.             }
  1042.         }
  1043.         msg_Dbg( p_demux, "seek: "I64Fd" seconds", p_sys->i_time /1000000 );
  1044.         /* set true movie time */
  1045. #endif
  1046.         if( !p_sys->i_time )
  1047.         {
  1048.             p_sys->i_time = i_date;
  1049.         }
  1050. #undef p_stream
  1051.         return VLC_SUCCESS;
  1052.     }
  1053.     else
  1054.     {
  1055.         msg_Err( p_demux, "shouldn't yet be executed" );
  1056.         return VLC_EGENERIC;
  1057.     }
  1058. }
  1059. /*****************************************************************************
  1060.  * Control:
  1061.  *****************************************************************************
  1062.  *
  1063.  *****************************************************************************/
  1064. static double ControlGetPosition( demux_t *p_demux )
  1065. {
  1066.     demux_sys_t *p_sys = p_demux->p_sys;
  1067.     if( p_sys->i_length > 0 )
  1068.     {
  1069.         return (double)p_sys->i_time / (double)( p_sys->i_length * (mtime_t)1000000 );
  1070.     }
  1071.     else if( stream_Size( p_demux->s ) > 0 )
  1072.     {
  1073.         unsigned int i;
  1074.         int64_t i_tmp;
  1075.         int64_t i64 = 0;
  1076.         /* search the more advanced selected es */
  1077.         for( i = 0; i < p_sys->i_track; i++ )
  1078.         {
  1079.             avi_track_t *tk = p_sys->track[i];
  1080.             if( tk->b_activated && tk->i_idxposc < tk->i_idxnb )
  1081.             {
  1082.                 i_tmp = tk->p_index[tk->i_idxposc].i_pos +
  1083.                         tk->p_index[tk->i_idxposc].i_length + 8;
  1084.                 if( i_tmp > i64 )
  1085.                 {
  1086.                     i64 = i_tmp;
  1087.                 }
  1088.             }
  1089.         }
  1090.         return (double)i64 / (double)stream_Size( p_demux->s );
  1091.     }
  1092.     return 0.0;
  1093. }
  1094. static int    Control( demux_t *p_demux, int i_query, va_list args )
  1095. {
  1096.     demux_sys_t *p_sys = p_demux->p_sys;
  1097.     int i;
  1098.     double   f, *pf;
  1099.     int64_t i64, *pi64;
  1100.     vlc_meta_t **pp_meta;
  1101.     switch( i_query )
  1102.     {
  1103.         case DEMUX_GET_POSITION:
  1104.             pf = (double*)va_arg( args, double * );
  1105.             *pf = ControlGetPosition( p_demux );
  1106.             return VLC_SUCCESS;
  1107.         case DEMUX_SET_POSITION:
  1108.             f = (double)va_arg( args, double );
  1109.             if( p_sys->b_seekable )
  1110.             {
  1111.                 i64 = (mtime_t)(1000000.0 * p_sys->i_length * f );
  1112.                 return Seek( p_demux, i64, (int)(f * 100) );
  1113.             }
  1114.             else
  1115.             {
  1116.                 int64_t i_pos = stream_Size( p_demux->s ) * f;
  1117.                 return stream_Seek( p_demux->s, i_pos );
  1118.             }
  1119.         case DEMUX_GET_TIME:
  1120.             pi64 = (int64_t*)va_arg( args, int64_t * );
  1121.             *pi64 = p_sys->i_time;
  1122.             return VLC_SUCCESS;
  1123.         case DEMUX_SET_TIME:
  1124.         {
  1125.             int i_percent = 0;
  1126.             i64 = (int64_t)va_arg( args, int64_t );
  1127.             if( p_sys->i_length > 0 )
  1128.             {
  1129.                 i_percent = 100 * i64 / (p_sys->i_length*1000000);
  1130.             }
  1131.             else if( p_sys->i_time > 0 )
  1132.             {
  1133.                 i_percent = (int)( 100.0 * ControlGetPosition( p_demux ) *
  1134.                                    (double)i64 / (double)p_sys->i_time );
  1135.             }
  1136.             return Seek( p_demux, i64, i_percent );
  1137.         }
  1138.         case DEMUX_GET_LENGTH:
  1139.             pi64 = (int64_t*)va_arg( args, int64_t * );
  1140.             *pi64 = p_sys->i_length * (mtime_t)1000000;
  1141.             return VLC_SUCCESS;
  1142.         case DEMUX_GET_FPS:
  1143.             pf = (double*)va_arg( args, double * );
  1144.             *pf = 0.0;
  1145.             for( i = 0; i < (int)p_sys->i_track; i++ )
  1146.             {
  1147.                 avi_track_t *tk = p_sys->track[i];
  1148.                 if( tk->i_cat == VIDEO_ES && tk->i_scale > 0)
  1149.                 {
  1150.                     *pf = (float)tk->i_rate / (float)tk->i_scale;
  1151.                     break;
  1152.                 }
  1153.             }
  1154.             return VLC_SUCCESS;
  1155.         case DEMUX_GET_META:
  1156.             pp_meta = (vlc_meta_t**)va_arg( args, vlc_meta_t** );
  1157.             *pp_meta = vlc_meta_Duplicate( p_sys->meta );
  1158.             return VLC_SUCCESS;
  1159.         default:
  1160.             return VLC_EGENERIC;
  1161.     }
  1162. }
  1163. /*****************************************************************************
  1164.  * Function to convert pts to chunk or byte
  1165.  *****************************************************************************/
  1166. static mtime_t AVI_PTSToChunk( avi_track_t *tk, mtime_t i_pts )
  1167. {
  1168.     return (mtime_t)((int64_t)i_pts *
  1169.                      (int64_t)tk->i_rate /
  1170.                      (int64_t)tk->i_scale /
  1171.                      (int64_t)1000000 );
  1172. }
  1173. static mtime_t AVI_PTSToByte( avi_track_t *tk, mtime_t i_pts )
  1174. {
  1175.     return (mtime_t)((int64_t)i_pts *
  1176.                      (int64_t)tk->i_rate /
  1177.                      (int64_t)tk->i_scale /
  1178.                      (int64_t)1000000 *
  1179.                      (int64_t)tk->i_samplesize );
  1180. }
  1181. static mtime_t AVI_GetDPTS( avi_track_t *tk, int64_t i_count )
  1182. {
  1183.     mtime_t i_dpts;
  1184.     i_dpts = (mtime_t)( (int64_t)1000000 *
  1185.                         (int64_t)i_count *
  1186.                         (int64_t)tk->i_scale /
  1187.                         (int64_t)tk->i_rate );
  1188.     if( tk->i_samplesize )
  1189.     {
  1190.         return i_dpts / tk->i_samplesize;
  1191.     }
  1192.     return i_dpts;
  1193. }
  1194. static mtime_t AVI_GetPTS( avi_track_t *tk )
  1195. {
  1196.     if( tk->i_samplesize )
  1197.     {
  1198.         int64_t i_count = 0;
  1199.         /* we need a valid entry we will emulate one */
  1200.         if( tk->i_idxposc == tk->i_idxnb )
  1201.         {
  1202.             if( tk->i_idxposc )
  1203.             {
  1204.                 /* use the last entry */
  1205.                 i_count = tk->p_index[tk->i_idxnb - 1].i_lengthtotal
  1206.                             + tk->p_index[tk->i_idxnb - 1].i_length;
  1207.             }
  1208.         }
  1209.         else
  1210.         {
  1211.             i_count = tk->p_index[tk->i_idxposc].i_lengthtotal;
  1212.         }
  1213.         return AVI_GetDPTS( tk, i_count + tk->i_idxposb );
  1214.     }
  1215.     else
  1216.     {
  1217.         if( tk->i_cat == AUDIO_ES )
  1218.         {
  1219.             return AVI_GetDPTS( tk, tk->i_blockno );
  1220.         }
  1221.         else
  1222.         {
  1223.             return AVI_GetDPTS( tk, tk->i_idxposc );
  1224.         }
  1225.     }
  1226. }
  1227. static int AVI_StreamChunkFind( demux_t *p_demux, unsigned int i_stream )
  1228. {
  1229.     demux_sys_t *p_sys = p_demux->p_sys;
  1230.     avi_packet_t avi_pk;
  1231.     int i_loop_count = 0;
  1232.     /* find first chunk of i_stream that isn't in index */
  1233.     if( p_sys->i_movi_lastchunk_pos >= p_sys->i_movi_begin + 12 )
  1234.     {
  1235.         stream_Seek( p_demux->s, p_sys->i_movi_lastchunk_pos );
  1236.         if( AVI_PacketNext( p_demux ) )
  1237.         {
  1238.             return VLC_EGENERIC;
  1239.         }
  1240.     }
  1241.     else
  1242.     {
  1243.         stream_Seek( p_demux->s, p_sys->i_movi_begin + 12 );
  1244.     }
  1245.     for( ;; )
  1246.     {
  1247.         if( p_demux->b_die ) return VLC_EGENERIC;
  1248.         if( AVI_PacketGetHeader( p_demux, &avi_pk ) )
  1249.         {
  1250.             msg_Warn( p_demux, "cannot get packet header" );
  1251.             return VLC_EGENERIC;
  1252.         }
  1253.         if( avi_pk.i_stream >= p_sys->i_track ||
  1254.             ( avi_pk.i_cat != AUDIO_ES && avi_pk.i_cat != VIDEO_ES ) )
  1255.         {
  1256.             if( AVI_PacketNext( p_demux ) )
  1257.             {
  1258.                 return VLC_EGENERIC;
  1259.             }
  1260.             /* Prevents from eating all the CPU with broken files.
  1261.              * This value should be low enough so that it doesn't
  1262.              * affect the reading speed too much. */
  1263.             if( !(++i_loop_count % 1024) )
  1264.             {
  1265.                 if( p_demux->b_die ) return VLC_EGENERIC;
  1266.                 msleep( 10000 );
  1267.                 if( !(i_loop_count % (1024 * 10)) )
  1268.                     msg_Warn( p_demux, "don't seem to find any data..." );
  1269.             }
  1270.         }
  1271.         else
  1272.         {
  1273.             /* add this chunk to the index */
  1274.             avi_entry_t index;
  1275.             index.i_id = avi_pk.i_fourcc;
  1276.             index.i_flags =
  1277.                AVI_GetKeyFlag(p_sys->track[avi_pk.i_stream]->i_codec,
  1278.                               avi_pk.i_peek);
  1279.             index.i_pos = avi_pk.i_pos;
  1280.             index.i_length = avi_pk.i_size;
  1281.             AVI_IndexAddEntry( p_sys, avi_pk.i_stream, &index );
  1282.             if( avi_pk.i_stream == i_stream  )
  1283.             {
  1284.                 return VLC_SUCCESS;
  1285.             }
  1286.             if( AVI_PacketNext( p_demux ) )
  1287.             {
  1288.                 return VLC_EGENERIC;
  1289.             }
  1290.         }
  1291.     }
  1292. }
  1293. /* be sure that i_ck will be a valid index entry */
  1294. static int AVI_StreamChunkSet( demux_t *p_demux, unsigned int i_stream,
  1295.                                unsigned int i_ck )
  1296. {
  1297.     demux_sys_t *p_sys = p_demux->p_sys;
  1298.     avi_track_t *p_stream = p_sys->track[i_stream];
  1299.     p_stream->i_idxposc = i_ck;
  1300.     p_stream->i_idxposb = 0;
  1301.     if(  i_ck >= p_stream->i_idxnb )
  1302.     {
  1303.         p_stream->i_idxposc = p_stream->i_idxnb - 1;
  1304.         do
  1305.         {
  1306.             p_stream->i_idxposc++;
  1307.             if( AVI_StreamChunkFind( p_demux, i_stream ) )
  1308.             {
  1309.                 return VLC_EGENERIC;
  1310.             }
  1311.         } while( p_stream->i_idxposc < i_ck );
  1312.     }
  1313.     return VLC_SUCCESS;
  1314. }
  1315. /* XXX FIXME up to now, we assume that all chunk are one after one */
  1316. static int AVI_StreamBytesSet( demux_t    *p_demux,
  1317.                                unsigned int i_stream,
  1318.                                off_t   i_byte )
  1319. {
  1320.     demux_sys_t *p_sys = p_demux->p_sys;
  1321.     avi_track_t *p_stream = p_sys->track[i_stream];
  1322.     if( ( p_stream->i_idxnb > 0 )
  1323.         &&( i_byte < p_stream->p_index[p_stream->i_idxnb - 1].i_lengthtotal +
  1324.                 p_stream->p_index[p_stream->i_idxnb - 1].i_length ) )
  1325.     {
  1326.         /* index is valid to find the ck */
  1327.         /* uses dichototmie to be fast enougth */
  1328.         int i_idxposc = __MIN( p_stream->i_idxposc, p_stream->i_idxnb - 1 );
  1329.         int i_idxmax  = p_stream->i_idxnb;
  1330.         int i_idxmin  = 0;
  1331.         for( ;; )
  1332.         {
  1333.             if( p_stream->p_index[i_idxposc].i_lengthtotal > i_byte )
  1334.             {
  1335.                 i_idxmax  = i_idxposc ;
  1336.                 i_idxposc = ( i_idxmin + i_idxposc ) / 2 ;
  1337.             }
  1338.             else
  1339.             {
  1340.                 if( p_stream->p_index[i_idxposc].i_lengthtotal +
  1341.                         p_stream->p_index[i_idxposc].i_length <= i_byte)
  1342.                 {
  1343.                     i_idxmin  = i_idxposc ;
  1344.                     i_idxposc = (i_idxmax + i_idxposc ) / 2 ;
  1345.                 }
  1346.                 else
  1347.                 {
  1348.                     p_stream->i_idxposc = i_idxposc;
  1349.                     p_stream->i_idxposb = i_byte -
  1350.                             p_stream->p_index[i_idxposc].i_lengthtotal;
  1351.                     return VLC_SUCCESS;
  1352.                 }
  1353.             }
  1354.         }
  1355.     }
  1356.     else
  1357.     {
  1358.         p_stream->i_idxposc = p_stream->i_idxnb - 1;
  1359.         p_stream->i_idxposb = 0;
  1360.         do
  1361.         {
  1362.             p_stream->i_idxposc++;
  1363.             if( AVI_StreamChunkFind( p_demux, i_stream ) )
  1364.             {
  1365.                 return VLC_EGENERIC;
  1366.             }
  1367.         } while( p_stream->p_index[p_stream->i_idxposc].i_lengthtotal +
  1368.                     p_stream->p_index[p_stream->i_idxposc].i_length <= i_byte );
  1369.         p_stream->i_idxposb = i_byte -
  1370.                        p_stream->p_index[p_stream->i_idxposc].i_lengthtotal;
  1371.         return VLC_SUCCESS;
  1372.     }
  1373. }
  1374. static int AVI_TrackSeek( demux_t *p_demux,
  1375.                            int i_stream,
  1376.                            mtime_t i_date )
  1377. {
  1378.     demux_sys_t  *p_sys = p_demux->p_sys;
  1379.     avi_track_t  *tk = p_sys->track[i_stream];
  1380. #define p_stream    p_sys->track[i_stream]
  1381.     mtime_t i_oldpts;
  1382.     i_oldpts = AVI_GetPTS( p_stream );
  1383.     if( !p_stream->i_samplesize )
  1384.     {
  1385.         if( AVI_StreamChunkSet( p_demux,
  1386.                                 i_stream,
  1387.                                 AVI_PTSToChunk( p_stream, i_date ) ) )
  1388.         {
  1389.             return VLC_EGENERIC;
  1390.         }
  1391.         if( p_stream->i_cat == AUDIO_ES )
  1392.         {
  1393.             unsigned int i;
  1394.             tk->i_blockno = 0;
  1395.             for( i = 0; i < tk->i_idxposc; i++ )
  1396.             {
  1397.                 if( tk->i_blocksize > 0 )
  1398.                 {
  1399.                     tk->i_blockno += ( tk->p_index[i].i_length + tk->i_blocksize - 1 ) / tk->i_blocksize;
  1400.                 }
  1401.                 else
  1402.                 {
  1403.                     tk->i_blockno++;
  1404.                 }
  1405.             }
  1406.         }
  1407.         msg_Dbg( p_demux,
  1408.                  "old:"I64Fd" %s new "I64Fd,
  1409.                  i_oldpts,
  1410.                  i_oldpts > i_date ? ">" : "<",
  1411.                  i_date );
  1412.         if( p_stream->i_cat == VIDEO_ES )
  1413.         {
  1414.             /* search key frame */
  1415.             if( i_date < i_oldpts )
  1416.             {
  1417.                 while( p_stream->i_idxposc > 0 &&
  1418.                    !( p_stream->p_index[p_stream->i_idxposc].i_flags &
  1419.                                                                 AVIIF_KEYFRAME ) )
  1420.                 {
  1421.                     if( AVI_StreamChunkSet( p_demux,
  1422.                                             i_stream,
  1423.                                             p_stream->i_idxposc - 1 ) )
  1424.                     {
  1425.                         return VLC_EGENERIC;
  1426.                     }
  1427.                 }
  1428.             }
  1429.             else
  1430.             {
  1431.                 while( p_stream->i_idxposc < p_stream->i_idxnb &&
  1432.                         !( p_stream->p_index[p_stream->i_idxposc].i_flags &
  1433.                                                                 AVIIF_KEYFRAME ) )
  1434.                 {
  1435.                     if( AVI_StreamChunkSet( p_demux,
  1436.                                             i_stream,
  1437.                                             p_stream->i_idxposc + 1 ) )
  1438.                     {
  1439.                         return VLC_EGENERIC;
  1440.                     }
  1441.                 }
  1442.             }
  1443.         }
  1444.     }
  1445.     else
  1446.     {
  1447.         if( AVI_StreamBytesSet( p_demux,
  1448.                                 i_stream,
  1449.                                 AVI_PTSToByte( p_stream, i_date ) ) )
  1450.         {
  1451.             return VLC_EGENERIC;
  1452.         }
  1453.     }
  1454.     return VLC_SUCCESS;
  1455. #undef p_stream
  1456. }
  1457. /****************************************************************************
  1458.  * Return VLC_TRUE if it's a key frame
  1459.  ****************************************************************************/
  1460. static int AVI_GetKeyFlag( vlc_fourcc_t i_fourcc, uint8_t *p_byte )
  1461. {
  1462.     switch( i_fourcc )
  1463.     {
  1464.         case FOURCC_DIV1:
  1465.             /* we have:
  1466.              *  startcode:      0x00000100   32bits
  1467.              *  framenumber     ?             5bits
  1468.              *  piture type     0(I),1(P)     2bits
  1469.              */
  1470.             if( GetDWBE( p_byte ) != 0x00000100 )
  1471.             {
  1472.                 /* it's not an msmpegv1 stream, strange...*/
  1473.                 return AVIIF_KEYFRAME;
  1474.             }
  1475.             return p_byte[4] & 0x06 ? 0 : AVIIF_KEYFRAME;
  1476.         case FOURCC_DIV2:
  1477.         case FOURCC_DIV3:   /* wmv1 also */
  1478.             /* we have
  1479.              *  picture type    0(I),1(P)     2bits
  1480.              */
  1481.             return p_byte[0] & 0xC0 ? 0 : AVIIF_KEYFRAME;
  1482.         case FOURCC_mp4v:
  1483.             /* we should find first occurrence of 0x000001b6 (32bits)
  1484.              *  startcode:      0x000001b6   32bits
  1485.              *  piture type     0(I),1(P)     2bits
  1486.              */
  1487.             if( GetDWBE( p_byte ) != 0x000001b6 )
  1488.             {
  1489.                 /* not true , need to find the first VOP header */
  1490.                 return AVIIF_KEYFRAME;
  1491.             }
  1492.             return p_byte[4] & 0xC0 ? 0 : AVIIF_KEYFRAME;
  1493.         default:
  1494.             /* I can't do it, so say yes */
  1495.             return AVIIF_KEYFRAME;
  1496.     }
  1497. }
  1498. vlc_fourcc_t AVI_FourccGetCodec( unsigned int i_cat, vlc_fourcc_t i_codec )
  1499. {
  1500.     switch( i_cat )
  1501.     {
  1502.         case AUDIO_ES:
  1503.             wf_tag_to_fourcc( i_codec, &i_codec, NULL );
  1504.             return i_codec;
  1505.         case VIDEO_ES:
  1506.             /* XXX DIV1 <- msmpeg4v1, DIV2 <- msmpeg4v2, DIV3 <- msmpeg4v3, mp4v for mpeg4 */
  1507.             switch( i_codec )
  1508.             {
  1509.                 case FOURCC_1:
  1510.                     return VLC_FOURCC('m','r','l','e');
  1511.                 case FOURCC_DIV1:
  1512.                 case FOURCC_div1:
  1513.                 case FOURCC_MPG4:
  1514.                 case FOURCC_mpg4:
  1515.                     return FOURCC_DIV1;
  1516.                 case FOURCC_DIV2:
  1517.                 case FOURCC_div2:
  1518.                 case FOURCC_MP42:
  1519.                 case FOURCC_mp42:
  1520.                 case FOURCC_MPG3:
  1521.                 case FOURCC_mpg3:
  1522.                     return FOURCC_DIV2;
  1523.                 case FOURCC_div3:
  1524.                 case FOURCC_MP43:
  1525.                 case FOURCC_mp43:
  1526.                 case FOURCC_DIV3:
  1527.                 case FOURCC_DIV4:
  1528.                 case FOURCC_div4:
  1529.                 case FOURCC_DIV5:
  1530.                 case FOURCC_div5:
  1531.                 case FOURCC_DIV6:
  1532.                 case FOURCC_div6:
  1533.                 case FOURCC_AP41:
  1534.                 case FOURCC_3IV1:
  1535.                 case FOURCC_3iv1:
  1536.                 case FOURCC_3IVD:
  1537.                 case FOURCC_3ivd:
  1538.                 case FOURCC_3VID:
  1539.                 case FOURCC_3vid:
  1540.                     return FOURCC_DIV3;
  1541.                 case FOURCC_DIVX:
  1542.                 case FOURCC_divx:
  1543.                 case FOURCC_MP4S:
  1544.                 case FOURCC_mp4s:
  1545.                 case FOURCC_M4S2:
  1546.                 case FOURCC_m4s2:
  1547.                 case FOURCC_xvid:
  1548.                 case FOURCC_XVID:
  1549.                 case FOURCC_XviD:
  1550.                 case FOURCC_DX50:
  1551.                 case FOURCC_dx50:
  1552.                 case FOURCC_mp4v:
  1553.                 case FOURCC_4:
  1554.                 case FOURCC_3IV2:
  1555.                 case FOURCC_3iv2:
  1556.                     return FOURCC_mp4v;
  1557.             }
  1558.         default:
  1559.             return VLC_FOURCC( 'u', 'n', 'd', 'f' );
  1560.     }
  1561. }
  1562. /****************************************************************************
  1563.  *
  1564.  ****************************************************************************/
  1565. static void AVI_ParseStreamHeader( vlc_fourcc_t i_id,
  1566.                                    int *pi_number, int *pi_type )
  1567. {
  1568. #define SET_PTR( p, v ) if( p ) *(p) = (v);
  1569.     int c1, c2;
  1570.     c1 = ((uint8_t *)&i_id)[0];
  1571.     c2 = ((uint8_t *)&i_id)[1];
  1572.     if( c1 < '0' || c1 > '9' || c2 < '0' || c2 > '9' )
  1573.     {
  1574.         SET_PTR( pi_number, 100 ); /* > max stream number */
  1575.         SET_PTR( pi_type, UNKNOWN_ES );
  1576.     }
  1577.     else
  1578.     {
  1579.         SET_PTR( pi_number, (c1 - '0') * 10 + (c2 - '0' ) );
  1580.         switch( VLC_TWOCC( ((uint8_t *)&i_id)[2], ((uint8_t *)&i_id)[3] ) )
  1581.         {
  1582.             case AVITWOCC_wb:
  1583.                 SET_PTR( pi_type, AUDIO_ES );
  1584.                 break;
  1585.             case AVITWOCC_dc:
  1586.             case AVITWOCC_db:
  1587.                 SET_PTR( pi_type, VIDEO_ES );
  1588.                 break;
  1589.             default:
  1590.                 SET_PTR( pi_type, UNKNOWN_ES );
  1591.                 break;
  1592.         }
  1593.     }
  1594. #undef SET_PTR
  1595. }
  1596. /****************************************************************************
  1597.  *
  1598.  ****************************************************************************/
  1599. static int AVI_PacketGetHeader( demux_t *p_demux, avi_packet_t *p_pk )
  1600. {
  1601.     uint8_t  *p_peek;
  1602.     if( stream_Peek( p_demux->s, &p_peek, 16 ) < 16 )
  1603.     {
  1604.         return VLC_EGENERIC;
  1605.     }
  1606.     p_pk->i_fourcc  = VLC_FOURCC( p_peek[0], p_peek[1], p_peek[2], p_peek[3] );
  1607.     p_pk->i_size    = GetDWLE( p_peek + 4 );
  1608.     p_pk->i_pos     = stream_Tell( p_demux->s );
  1609.     if( p_pk->i_fourcc == AVIFOURCC_LIST || p_pk->i_fourcc == AVIFOURCC_RIFF )
  1610.     {
  1611.         p_pk->i_type = VLC_FOURCC( p_peek[8],  p_peek[9],
  1612.                                    p_peek[10], p_peek[11] );
  1613.     }
  1614.     else
  1615.     {
  1616.         p_pk->i_type = 0;
  1617.     }
  1618.     memcpy( p_pk->i_peek, p_peek + 8, 8 );
  1619.     AVI_ParseStreamHeader( p_pk->i_fourcc, &p_pk->i_stream, &p_pk->i_cat );
  1620.     return VLC_SUCCESS;
  1621. }
  1622. static int AVI_PacketNext( demux_t *p_demux )
  1623. {
  1624.     avi_packet_t    avi_ck;
  1625.     int             i_skip = 0;
  1626.     if( AVI_PacketGetHeader( p_demux, &avi_ck ) )
  1627.     {
  1628.         return VLC_EGENERIC;
  1629.     }
  1630.     if( avi_ck.i_fourcc == AVIFOURCC_LIST &&
  1631.         ( avi_ck.i_type == AVIFOURCC_rec || avi_ck.i_type == AVIFOURCC_movi ) )
  1632.     {
  1633.         i_skip = 12;
  1634.     }
  1635.     else if( avi_ck.i_fourcc == AVIFOURCC_RIFF &&
  1636.              avi_ck.i_type == AVIFOURCC_AVIX )
  1637.     {
  1638.         i_skip = 24;
  1639.     }
  1640.     else
  1641.     {
  1642.         i_skip = __EVEN( avi_ck.i_size ) + 8;
  1643.     }
  1644.     if( stream_Read( p_demux->s, NULL, i_skip ) != i_skip )
  1645.     {
  1646.         return VLC_EGENERIC;
  1647.     }
  1648.     return VLC_SUCCESS;
  1649. }
  1650. static int AVI_PacketRead( demux_t   *p_demux,
  1651.                            avi_packet_t     *p_pk,
  1652.                            block_t          **pp_frame )
  1653. {
  1654.     size_t i_size;
  1655.     i_size = __EVEN( p_pk->i_size + 8 );
  1656.     if( ( *pp_frame = stream_Block( p_demux->s, i_size ) ) == NULL )
  1657.     {
  1658.         return VLC_EGENERIC;
  1659.     }
  1660.     (*pp_frame)->p_buffer += 8;
  1661.     (*pp_frame)->i_buffer -= 8;
  1662.     if( i_size != p_pk->i_size + 8 )
  1663.     {
  1664.         (*pp_frame)->i_buffer--;
  1665.     }
  1666.     return VLC_SUCCESS;
  1667. }
  1668. static int AVI_PacketSearch( demux_t *p_demux )
  1669. {
  1670.     demux_sys_t     *p_sys = p_demux->p_sys;
  1671.     avi_packet_t    avi_pk;
  1672.     int             i_count = 0;
  1673.     for( ;; )
  1674.     {
  1675.         if( stream_Read( p_demux->s, NULL, 1 ) != 1 )
  1676.         {
  1677.             return VLC_EGENERIC;
  1678.         }
  1679.         AVI_PacketGetHeader( p_demux, &avi_pk );
  1680.         if( avi_pk.i_stream < p_sys->i_track &&
  1681.             ( avi_pk.i_cat == AUDIO_ES || avi_pk.i_cat == VIDEO_ES ) )
  1682.         {
  1683.             return VLC_SUCCESS;
  1684.         }
  1685.         switch( avi_pk.i_fourcc )
  1686.         {
  1687.             case AVIFOURCC_JUNK:
  1688.             case AVIFOURCC_LIST:
  1689.             case AVIFOURCC_RIFF:
  1690.             case AVIFOURCC_idx1:
  1691.                 return VLC_SUCCESS;
  1692.         }
  1693.         /* Prevents from eating all the CPU with broken files.
  1694.          * This value should be low enough so that it doesn't affect the
  1695.          * reading speed too much (not that we care much anyway because
  1696.          * this code is called only on broken files). */
  1697.         if( !(++i_count % 1024) )
  1698.         {
  1699.             if( p_demux->b_die ) return VLC_EGENERIC;
  1700.             msleep( 10000 );
  1701.             if( !(i_count % (1024 * 10)) )
  1702.                 msg_Warn( p_demux, "trying to resync..." );
  1703.         }
  1704.     }
  1705. }
  1706. /****************************************************************************
  1707.  * Index stuff.
  1708.  ****************************************************************************/
  1709. static void AVI_IndexAddEntry( demux_sys_t *p_sys,
  1710.                                int i_stream,
  1711.                                avi_entry_t *p_index)
  1712. {
  1713.     avi_track_t *tk = p_sys->track[i_stream];
  1714.     /* Update i_movi_lastchunk_pos */
  1715.     if( p_sys->i_movi_lastchunk_pos < p_index->i_pos )
  1716.     {
  1717.         p_sys->i_movi_lastchunk_pos = p_index->i_pos;
  1718.     }
  1719.     /* add the entry */
  1720.     if( tk->i_idxnb >= tk->i_idxmax )
  1721.     {
  1722.         tk->i_idxmax += 16384;
  1723.         tk->p_index = realloc( tk->p_index,
  1724.                                tk->i_idxmax * sizeof( avi_entry_t ) );
  1725.         if( tk->p_index == NULL )
  1726.         {
  1727.             return;
  1728.         }
  1729.     }
  1730.     /* calculate cumulate length */
  1731.     if( tk->i_idxnb > 0 )
  1732.     {
  1733.         p_index->i_lengthtotal =
  1734.             tk->p_index[tk->i_idxnb - 1].i_length +
  1735.                 tk->p_index[tk->i_idxnb - 1].i_lengthtotal;
  1736.     }
  1737.     else
  1738.     {
  1739.         p_index->i_lengthtotal = 0;
  1740.     }
  1741.     tk->p_index[tk->i_idxnb++] = *p_index;
  1742. }
  1743. static int AVI_IndexLoad_idx1( demux_t *p_demux )
  1744. {
  1745.     demux_sys_t *p_sys = p_demux->p_sys;
  1746.     avi_chunk_list_t    *p_riff;
  1747.     avi_chunk_list_t    *p_movi;
  1748.     avi_chunk_idx1_t    *p_idx1;
  1749.     unsigned int i_stream;
  1750.     unsigned int i_index;
  1751.     off_t        i_offset;
  1752.     unsigned int i;
  1753.     vlc_bool_t b_keyset[100];
  1754.     p_riff = AVI_ChunkFind( &p_sys->ck_root, AVIFOURCC_RIFF, 0);
  1755.     p_idx1 = AVI_ChunkFind( p_riff, AVIFOURCC_idx1, 0);
  1756.     p_movi = AVI_ChunkFind( p_riff, AVIFOURCC_movi, 0);
  1757.     if( !p_idx1 )
  1758.     {
  1759.         msg_Warn( p_demux, "cannot find idx1 chunk, no index defined" );
  1760.         return VLC_EGENERIC;
  1761.     }
  1762.     /* *** calculate offset *** */
  1763.     /* Well, avi is __SHIT__ so test more than one entry
  1764.      * (needed for some avi files) */
  1765.     i_offset = 0;
  1766.     for( i = 0; i < __MIN( p_idx1->i_entry_count, 10 ); i++ )
  1767.     {
  1768.         if( p_idx1->entry[i].i_pos < p_movi->i_chunk_pos )
  1769.         {
  1770.             i_offset = p_movi->i_chunk_pos + 8;
  1771.             break;
  1772.         }
  1773.     }
  1774.     /* Reset b_keyset */
  1775.     for( i_stream = 0; i_stream < p_sys->i_track; i_stream++ )
  1776.         b_keyset[i_stream] = VLC_FALSE;
  1777.     for( i_index = 0; i_index < p_idx1->i_entry_count; i_index++ )
  1778.     {
  1779.         unsigned int i_cat;
  1780.         AVI_ParseStreamHeader( p_idx1->entry[i_index].i_fourcc,
  1781.                                &i_stream,
  1782.                                &i_cat );
  1783.         if( i_stream < p_sys->i_track &&
  1784.             i_cat == p_sys->track[i_stream]->i_cat )
  1785.         {
  1786.             avi_entry_t index;
  1787.             index.i_id      = p_idx1->entry[i_index].i_fourcc;
  1788.             index.i_flags   =
  1789.                 p_idx1->entry[i_index].i_flags&(~AVIIF_FIXKEYFRAME);
  1790.             index.i_pos     = p_idx1->entry[i_index].i_pos + i_offset;
  1791.             index.i_length  = p_idx1->entry[i_index].i_length;
  1792.             AVI_IndexAddEntry( p_sys, i_stream, &index );
  1793.             if( index.i_flags&AVIIF_KEYFRAME )
  1794.                 b_keyset[i_stream] = VLC_TRUE;
  1795.         }
  1796.     }
  1797.     for( i_stream = 0; i_stream < p_sys->i_track; i_stream++ )
  1798.     {
  1799.         if( !b_keyset[i_stream] )
  1800.         {
  1801.             avi_track_t *tk = p_sys->track[i_stream];
  1802.             msg_Dbg( p_demux, "no key frame set for track %d", i_stream );
  1803.             for( i_index = 0; i_index < tk->i_idxnb; i_index++ )
  1804.                 tk->p_index[i_index].i_flags |= AVIIF_KEYFRAME;
  1805.         }
  1806.     }
  1807.     return VLC_SUCCESS;
  1808. }
  1809. static void __Parse_indx( demux_t    *p_demux,
  1810.                           int               i_stream,
  1811.                           avi_chunk_indx_t  *p_indx )
  1812. {
  1813.     demux_sys_t         *p_sys    = p_demux->p_sys;
  1814.     avi_entry_t     index;
  1815.     int32_t             i;
  1816.     msg_Dbg( p_demux, "loading subindex(0x%x) %d entries", p_indx->i_indextype, p_indx->i_entriesinuse );
  1817.     if( p_indx->i_indexsubtype == 0 )
  1818.     {
  1819.         for( i = 0; i < p_indx->i_entriesinuse; i++ )
  1820.         {
  1821.             index.i_id      = p_indx->i_id;
  1822.             index.i_flags   = p_indx->idx.std[i].i_size & 0x80000000 ? 0 : AVIIF_KEYFRAME;
  1823.             index.i_pos     = p_indx->i_baseoffset + p_indx->idx.std[i].i_offset - 8;
  1824.             index.i_length  = p_indx->idx.std[i].i_size&0x7fffffff;
  1825.             AVI_IndexAddEntry( p_sys, i_stream, &index );
  1826.         }
  1827.     }
  1828.     else if( p_indx->i_indexsubtype == AVI_INDEX_2FIELD )
  1829.     {
  1830.         for( i = 0; i < p_indx->i_entriesinuse; i++ )
  1831.         {
  1832.             index.i_id      = p_indx->i_id;
  1833.             index.i_flags   = p_indx->idx.field[i].i_size & 0x80000000 ? 0 : AVIIF_KEYFRAME;
  1834.             index.i_pos     = p_indx->i_baseoffset + p_indx->idx.field[i].i_offset - 8;
  1835.             index.i_length  = p_indx->idx.field[i].i_size;
  1836.             AVI_IndexAddEntry( p_sys, i_stream, &index );
  1837.         }
  1838.     }
  1839.     else
  1840.     {
  1841.         msg_Warn( p_demux, "unknown subtype index(0x%x)", p_indx->i_indexsubtype );
  1842.     }
  1843. }
  1844. static void AVI_IndexLoad_indx( demux_t *p_demux )
  1845. {
  1846.     demux_sys_t         *p_sys = p_demux->p_sys;
  1847.     unsigned int        i_stream;
  1848.     int32_t             i;
  1849.     avi_chunk_list_t    *p_riff;
  1850.     avi_chunk_list_t    *p_hdrl;
  1851.     p_riff = AVI_ChunkFind( &p_sys->ck_root, AVIFOURCC_RIFF, 0);
  1852.     p_hdrl = AVI_ChunkFind( p_riff, AVIFOURCC_hdrl, 0 );
  1853.     for( i_stream = 0; i_stream < p_sys->i_track; i_stream++ )
  1854.     {
  1855.         avi_chunk_list_t    *p_strl;
  1856.         avi_chunk_indx_t    *p_indx;
  1857. #define p_stream  p_sys->track[i_stream]
  1858.         p_strl = AVI_ChunkFind( p_hdrl, AVIFOURCC_strl, i_stream );
  1859.         p_indx = AVI_ChunkFind( p_strl, AVIFOURCC_indx, 0 );
  1860.         if( !p_indx )
  1861.         {
  1862.             msg_Warn( p_demux, "cannot find indx (misdetect/broken OpenDML file?)" );
  1863.             continue;
  1864.         }
  1865.         if( p_indx->i_indextype == AVI_INDEX_OF_CHUNKS )
  1866.         {
  1867.             __Parse_indx( p_demux, i_stream, p_indx );
  1868.         }
  1869.         else if( p_indx->i_indextype == AVI_INDEX_OF_INDEXES )
  1870.         {
  1871.             avi_chunk_t    ck_sub;
  1872.             for( i = 0; i < p_indx->i_entriesinuse; i++ )
  1873.             {
  1874.                 if( stream_Seek( p_demux->s, p_indx->idx.super[i].i_offset )||
  1875.                     AVI_ChunkRead( p_demux->s, &ck_sub, NULL  ) )
  1876.                 {
  1877.                     break;
  1878.                 }
  1879.                 __Parse_indx( p_demux, i_stream, &ck_sub.indx );
  1880.             }
  1881.         }
  1882.         else
  1883.         {
  1884.             msg_Warn( p_demux, "unknown type index(0x%x)", p_indx->i_indextype );
  1885.         }
  1886. #undef p_stream
  1887.     }
  1888. }
  1889. static void AVI_IndexLoad( demux_t *p_demux )
  1890. {
  1891.     demux_sys_t *p_sys = p_demux->p_sys;
  1892.     unsigned int i_stream;
  1893.     for( i_stream = 0; i_stream < p_sys->i_track; i_stream++ )
  1894.     {
  1895.         p_sys->track[i_stream]->i_idxnb  = 0;
  1896.         p_sys->track[i_stream]->i_idxmax = 0;
  1897.         p_sys->track[i_stream]->p_index  = NULL;
  1898.     }
  1899.     if( p_sys->b_odml )
  1900.     {
  1901.         AVI_IndexLoad_indx( p_demux );
  1902.     }
  1903.     else  if( AVI_IndexLoad_idx1( p_demux ) )
  1904.     {
  1905.         /* try indx if idx1 failed as some "normal" file have indx too */
  1906.         AVI_IndexLoad_indx( p_demux );
  1907.     }
  1908.     for( i_stream = 0; i_stream < p_sys->i_track; i_stream++ )
  1909.     {
  1910.         msg_Dbg( p_demux, "stream[%d] created %d index entries",
  1911.                 i_stream, p_sys->track[i_stream]->i_idxnb );
  1912.     }
  1913. }
  1914. static void AVI_IndexCreate( demux_t *p_demux )
  1915. {
  1916.     demux_sys_t *p_sys = p_demux->p_sys;
  1917.     avi_chunk_list_t    *p_riff;
  1918.     avi_chunk_list_t    *p_movi;
  1919.     unsigned int i_stream;
  1920.     off_t i_movi_end;
  1921.     p_riff = AVI_ChunkFind( &p_sys->ck_root, AVIFOURCC_RIFF, 0);
  1922.     p_movi = AVI_ChunkFind( p_riff, AVIFOURCC_movi, 0);
  1923.     if( !p_movi )
  1924.     {
  1925.         msg_Err( p_demux, "cannot find p_movi" );
  1926.         return;
  1927.     }
  1928.     for( i_stream = 0; i_stream < p_sys->i_track; i_stream++ )
  1929.     {
  1930.         p_sys->track[i_stream]->i_idxnb  = 0;
  1931.         p_sys->track[i_stream]->i_idxmax = 0;
  1932.         p_sys->track[i_stream]->p_index  = NULL;
  1933.     }
  1934.     i_movi_end = __MIN( (off_t)(p_movi->i_chunk_pos + p_movi->i_chunk_size),
  1935.                         stream_Size( p_demux->s ) );
  1936.     stream_Seek( p_demux->s, p_movi->i_chunk_pos + 12 );
  1937.     msg_Warn( p_demux, "creating index from LIST-movi, will take time !" );
  1938.     for( ;; )
  1939.     {
  1940.         avi_packet_t pk;
  1941.         if( p_demux->b_die )
  1942.         {
  1943.             return;
  1944.         }
  1945.         if( AVI_PacketGetHeader( p_demux, &pk ) )
  1946.         {
  1947.             break;
  1948.         }
  1949.         if( pk.i_stream < p_sys->i_track &&
  1950.             pk.i_cat == p_sys->track[pk.i_stream]->i_cat )
  1951.         {
  1952.             avi_entry_t index;
  1953.             index.i_id      = pk.i_fourcc;
  1954.             index.i_flags   =
  1955.                AVI_GetKeyFlag(p_sys->track[pk.i_stream]->i_codec, pk.i_peek);
  1956.             index.i_pos     = pk.i_pos;
  1957.             index.i_length  = pk.i_size;
  1958.             AVI_IndexAddEntry( p_sys, pk.i_stream, &index );
  1959.         }
  1960.         else
  1961.         {
  1962.             switch( pk.i_fourcc )
  1963.             {
  1964.                 case AVIFOURCC_idx1:
  1965.                     if( p_sys->b_odml )
  1966.                     {
  1967.                         avi_chunk_list_t *p_sysx;
  1968.                         p_sysx = AVI_ChunkFind( &p_sys->ck_root,
  1969.                                                 AVIFOURCC_RIFF, 1 );
  1970.                         msg_Dbg( p_demux, "looking for new RIFF chunk" );
  1971.                         if( stream_Seek( p_demux->s, p_sysx->i_chunk_pos + 24))
  1972.                         {
  1973.                             goto print_stat;
  1974.                         }
  1975.                         break;
  1976.                     }
  1977.                     goto print_stat;
  1978.                 case AVIFOURCC_RIFF:
  1979.                         msg_Dbg( p_demux, "new RIFF chunk found" );
  1980.                 case AVIFOURCC_rec:
  1981.                 case AVIFOURCC_JUNK:
  1982.                     break;
  1983.                 default:
  1984.                     msg_Warn( p_demux, "need resync, probably broken avi" );
  1985.                     if( AVI_PacketSearch( p_demux ) )
  1986.                     {
  1987.                         msg_Warn( p_demux, "lost sync, abord index creation" );
  1988.                         goto print_stat;
  1989.                     }
  1990.             }
  1991.         }
  1992.         if( ( !p_sys->b_odml && pk.i_pos + pk.i_size >= i_movi_end ) ||
  1993.             AVI_PacketNext( p_demux ) )
  1994.         {
  1995.             break;
  1996.         }
  1997.     }
  1998. print_stat:
  1999.     for( i_stream = 0; i_stream < p_sys->i_track; i_stream++ )
  2000.     {
  2001.         msg_Dbg( p_demux,
  2002.                 "stream[%d] creating %d index entries",
  2003.                 i_stream,
  2004.                 p_sys->track[i_stream]->i_idxnb );
  2005.     }
  2006. }
  2007. /*****************************************************************************
  2008.  * Stream management
  2009.  *****************************************************************************/
  2010. static int AVI_TrackStopFinishedStreams( demux_t *p_demux )
  2011. {
  2012.     demux_sys_t *p_sys = p_demux->p_sys;
  2013.     unsigned int i;
  2014.     int b_end = VLC_TRUE;
  2015.     for( i = 0; i < p_sys->i_track; i++ )
  2016.     {
  2017.         avi_track_t *tk = p_sys->track[i];
  2018.         if( tk->i_idxposc >= tk->i_idxnb )
  2019.         {
  2020.             tk->b_activated = VLC_FALSE;
  2021.             es_out_Control( p_demux->out, ES_OUT_SET_ES_STATE, tk->p_es, VLC_FALSE );
  2022.         }
  2023.         else
  2024.         {
  2025.             b_end = VLC_FALSE;
  2026.         }
  2027.     }
  2028.     return( b_end );
  2029. }
  2030. /****************************************************************************
  2031.  * AVI_MovieGetLength give max streams length in second
  2032.  ****************************************************************************/
  2033. static mtime_t  AVI_MovieGetLength( demux_t *p_demux )
  2034. {
  2035.     demux_sys_t  *p_sys = p_demux->p_sys;
  2036.     mtime_t      i_maxlength = 0;
  2037.     unsigned int i;
  2038.     for( i = 0; i < p_sys->i_track; i++ )
  2039.     {
  2040.         avi_track_t *tk = p_sys->track[i];
  2041.         mtime_t i_length;
  2042.         /* fix length for each stream */
  2043.         if( tk->i_idxnb < 1 || !tk->p_index )
  2044.         {
  2045.             continue;
  2046.         }
  2047.         if( tk->i_samplesize )
  2048.         {
  2049.             i_length = AVI_GetDPTS( tk,
  2050.                                     tk->p_index[tk->i_idxnb-1].i_lengthtotal +
  2051.                                         tk->p_index[tk->i_idxnb-1].i_length );
  2052.         }
  2053.         else
  2054.         {
  2055.             i_length = AVI_GetDPTS( tk, tk->i_idxnb );
  2056.         }
  2057.         i_length /= (mtime_t)1000000;    /* in seconds */
  2058.         msg_Dbg( p_demux,
  2059.                  "stream[%d] length:"I64Fd" (based on index)",
  2060.                  i,
  2061.                  i_length );
  2062.         i_maxlength = __MAX( i_maxlength, i_length );
  2063.     }
  2064.     return i_maxlength;
  2065. }