avi.c
上传用户:kjfoods
上传日期:2020-07-06
资源大小:29949k
文件大小:81k
源码类别:

midi

开发平台:

Unix_Linux

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