/*****************************************************************************
* avi.c : AVI file Stream input module for vlc
*****************************************************************************
- * Copyright (C) 2001 VideoLAN
- * $Id: avi.c,v 1.79 2003/11/28 13:24:52 fenrir Exp $
+ * Copyright (C) 2001-2004 VideoLAN
+ * $Id: avi.c,v 1.85 2004/01/25 20:05:28 hartman Exp $
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
*
* This program is free software; you can redistribute it and/or modify
#include <vlc/vlc.h>
#include <vlc/input.h>
+#include "vlc_playlist.h"
#include "codecs.h"
#include "libavi.h"
/*****************************************************************************
* Module descriptor
*****************************************************************************/
+
+#define INTERLEAVE_TEXT N_("Force interleaved method" )
+#define INTERLEAVE_LONGTEXT N_( "Force interleaved method" )
+
+#define INDEX_TEXT N_("Force index creation")
+#define INDEX_LONGTEXT N_( \
+ "Recreate a index for the AVI file so we can seek trough it more reliably." )
+
static int Open ( vlc_object_t * );
static void Close ( vlc_object_t * );
vlc_module_begin();
- add_category_hint( N_("avi-demuxer"), NULL, VLC_TRUE );
- add_bool( "avi-interleaved", 0, NULL,
- N_("force interleaved method"),
- N_("force interleaved method"), VLC_TRUE );
- add_bool( "avi-index", 0, NULL,
- N_("force index creation"),
- N_("force index creation"), VLC_TRUE );
-
- set_description( N_("AVI demuxer") );
+ set_description( _("AVI demuxer") );
set_capability( "demux", 212 );
+
+ add_bool( "avi-interleaved", 0, NULL,
+ INTERLEAVE_TEXT, INTERLEAVE_LONGTEXT, VLC_TRUE );
+ add_bool( "avi-index", 0, NULL,
+ INDEX_TEXT, INDEX_LONGTEXT, VLC_TRUE );
+
set_callbacks( Open, Close );
vlc_module_end();
static int AVI_TrackSeek ( input_thread_t *, int, mtime_t );
static int AVI_TrackStopFinishedStreams( input_thread_t *);
+/* Remarks:
+ - For VBR mp3 stream:
+ count blocks by rounded-up chunksizes instead of chunks
+ we need full emulation of dshow avi demuxer bugs :(
+ fixes silly nandub-style a-v delaying in avi with vbr mp3...
+ (from mplayer 2002/08/02)
+ - to complete....
+ */
+
/*****************************************************************************
* Open: check file and initializes AVI structures
*****************************************************************************/
p_avih->i_flags&AVIF_ISINTERLEAVED?" IS_INTERLEAVED":"",
p_avih->i_flags&AVIF_TRUSTCKTYPE?" TRUST_CKTYPE":"" );
{
+ playlist_t *p_playlist = (playlist_t *)vlc_object_find( p_input,
+ VLC_OBJECT_PLAYLIST, FIND_PARENT);
input_info_category_t *p_cat = input_InfoCategory( p_input, _("Avi") );
- input_AddInfo( p_cat, _("Number of Streams"), "%d", i_track );
+
+ input_AddInfo( p_cat, _("Number of streams"), "%d", i_track );
input_AddInfo( p_cat, _("Flags"), "%s%s%s%s",
p_avih->i_flags&AVIF_HASINDEX?" HAS_INDEX":"",
p_avih->i_flags&AVIF_MUSTUSEINDEX?" MUST_USE_INDEX":"",
p_avih->i_flags&AVIF_ISINTERLEAVED?" IS_INTERLEAVED":"",
p_avih->i_flags&AVIF_TRUSTCKTYPE?" TRUST_CKTYPE":"" );
+ if( p_playlist )
+ {
+ playlist_AddInfo( p_playlist, -1 , _("Avi"),
+ _("Number of streams"), "%d", i_track );
+ playlist_AddInfo( p_playlist, -1 , _("Avi"),
+ _("Flags"), "%s%s%s%s",
+ p_avih->i_flags&AVIF_HASINDEX?" HAS_INDEX":"",
+ p_avih->i_flags&AVIF_MUSTUSEINDEX?" MUST_USE_INDEX":"",
+ p_avih->i_flags&AVIF_ISINTERLEAVED?" IS_INTERLEAVED":"",
+ p_avih->i_flags&AVIF_TRUSTCKTYPE?" TRUST_CKTYPE":"" );
+ vlc_object_release( p_playlist );
+ }
}
/* now read info on each stream and create ES */
tk->i_idxposc = 0;
tk->i_idxposb = 0;
+ tk->i_blockno = 0;
+ tk->i_blocksize = 0;
+
p_auds = (void*)p_vids = (void*)AVI_ChunkFind( p_strl, AVIFOURCC_strf, 0 );
if( p_strl == NULL || p_strh == NULL || p_auds == NULL || p_vids == NULL )
tk->i_cat = AUDIO_ES;
tk->i_codec = AVI_FourccGetCodec( AUDIO_ES,
p_auds->p_wf->wFormatTag );
+ if( ( tk->i_blocksize = p_auds->p_wf->nBlockAlign ) == 0 )
+ {
+ if( p_auds->p_wf->wFormatTag == 1 )
+ {
+ tk->i_blocksize = p_auds->p_wf->nChannels * (p_auds->p_wf->wBitsPerSample/8);
+ }
+ else
+ {
+ tk->i_blocksize = 1;
+ }
+ }
es_format_Init( &fmt, AUDIO_ES, tk->i_codec );
fmt.audio.i_channels = p_auds->p_wf->nChannels;
if( p_sys->i_track <= 0 )
{
- msg_Err( p_input, "No valid track" );
+ msg_Err( p_input, "no valid track" );
goto error;
}
}
else
{
- toread[i_track].i_toread--;
+ int i_length = tk->p_index[tk->i_idxposc].i_length;
+
tk->i_idxposc++;
+ if( tk->i_cat == AUDIO_ES )
+ {
+ tk->i_blockno += tk->i_blocksize > 0 ? ( i_length + tk->i_blocksize - 1 ) / tk->i_blocksize : 1;
+ }
+ toread[i_track].i_toread--;
}
if( tk->i_idxposc < tk->i_idxnb)
}
else
{
+ if( p_stream->i_cat == AUDIO_ES )
+ {
+ p_stream->i_blockno += p_stream->i_blocksize > 0 ? ( avi_pk.i_size + p_stream->i_blocksize - 1 ) / p_stream->i_blocksize : 1;
+ }
p_stream->i_idxposc++;
}
/* p_sys->i_time = __MAX( AVI_GetPTS( p_stream ), p_sys->i_time );*/
}
}
- msg_Dbg( p_input, "seek: "I64Fd" secondes", p_sys->i_time /1000000 );
+ msg_Dbg( p_input, "seek: "I64Fd" seconds", p_sys->i_time /1000000 );
/* set true movie time */
#endif
if( !p_sys->i_time )
{
f = (double)va_arg( args, double );
i64 = (mtime_t)(1000000.0 * p_sys->i_length * f );
- return Seek( p_input, i64, (int)(f * 100) );
+ return Seek( p_input, i64, (int)(f * 100) ) < 0 ? VLC_EGENERIC : VLC_SUCCESS;
}
return demux_vaControlDefault( p_input, i_query, args );
i64 = (int64_t)va_arg( args, int64_t );
if( p_sys->i_length > 0 )
{
- i_percent = 100 * i64 / (p_sys->i_length*1000000ULL);
+ i_percent = 100 * i64 / (p_sys->i_length*1000000);
}
else if( p_sys->i_time > 0 )
{
}
else
{
- return AVI_GetDPTS( tk, tk->i_idxposc );
+ if( tk->i_cat == AUDIO_ES )
+ {
+ return AVI_GetDPTS( tk, tk->i_blockno );
+ }
+ else
+ {
+ return AVI_GetDPTS( tk, tk->i_idxposc );
+ }
}
}
mtime_t i_date )
{
demux_sys_t *p_sys = p_input->p_demux_data;
+ avi_track_t *tk = p_sys->track[i_stream];
+
#define p_stream p_sys->track[i_stream]
mtime_t i_oldpts;
return VLC_EGENERIC;
}
+ if( p_stream->i_cat == AUDIO_ES )
+ {
+ unsigned int i;
+ tk->i_blockno = 0;
+ for( i = 0; i < tk->i_idxposc; i++ )
+ {
+ if( tk->i_blocksize > 0 )
+ {
+ tk->i_blockno += ( tk->p_index[i].i_length + tk->i_blocksize - 1 ) / tk->i_blocksize;
+ }
+ else
+ {
+ tk->i_blockno++;
+ }
+ }
+ }
+
msg_Dbg( p_input,
"old:"I64Fd" %s new "I64Fd,
i_oldpts,
case FOURCC_XVID:
case FOURCC_XviD:
case FOURCC_DX50:
+ case FOURCC_dx50:
case FOURCC_mp4v:
case FOURCC_4:
case FOURCC_3IV2:
}
/* *** calculate offset *** */
- /* Well, avi is __SHIT__ so test more than one entry
+ /* Well, avi is __SHIT__ so test more than one entry
* (needed for some avi files) */
i_offset = 0;
for( i = 0; i < __MIN( p_idx1->i_entry_count, 10 ); i++ )