# include "config.h"
#endif
-#include <vlc/vlc.h>
+#include <vlc_common.h>
+#include <vlc_plugin.h>
#include <vlc_demux.h>
#include <vlc_interface.h>
static int Open ( vlc_object_t * );
static void Close( vlc_object_t * );
-static int pi_index[] = {0,1,2};
+static const int pi_index[] = {0,1,2};
-static const char *ppsz_indexes[] = { N_("Ask"), N_("Always fix"),
+static const char *const ppsz_indexes[] = { N_("Ask"), N_("Always fix"),
N_("Never fix") };
-vlc_module_begin();
- set_shortname( "AVI" );
- set_description( _("AVI demuxer") );
- set_capability( "demux2", 212 );
- set_category( CAT_INPUT );
- set_subcategory( SUBCAT_INPUT_DEMUX );
+vlc_module_begin ()
+ set_shortname( "AVI" )
+ set_description( N_("AVI demuxer") )
+ set_capability( "demux", 212 )
+ set_category( CAT_INPUT )
+ set_subcategory( SUBCAT_INPUT_DEMUX )
add_bool( "avi-interleaved", 0, NULL,
- INTERLEAVE_TEXT, INTERLEAVE_LONGTEXT, true );
+ INTERLEAVE_TEXT, INTERLEAVE_LONGTEXT, true )
add_integer( "avi-index", 0, NULL,
- INDEX_TEXT, INDEX_LONGTEXT, false );
- change_integer_list( pi_index, ppsz_indexes, 0 );
+ INDEX_TEXT, INDEX_LONGTEXT, false )
+ change_integer_list( pi_index, ppsz_indexes, NULL )
- set_callbacks( Open, Close );
-vlc_module_end();
+ set_callbacks( Open, Close )
+vlc_module_end ()
/*****************************************************************************
* Local prototypes
/* meta */
vlc_meta_t *meta;
-
- /* Progress box */
- mtime_t last_update;
- int i_dialog_id;
};
static inline off_t __EVEN( off_t i )
if( ( p_sys->meta = vlc_meta_New() ) )
{
char buffer[200];
- sprintf( buffer, "%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":"" );
+ snprintf( buffer, sizeof(buffer), "%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_meta_SetSetting( p_sys->meta, buffer );
}
{
avi_track_t *tk = malloc( sizeof( avi_track_t ) );
if( !tk )
- {
- msg_Err( p_demux, "Out of memory" );
goto error;
- }
avi_chunk_list_t *p_strl = AVI_ChunkFind( p_hdrl, AVIFOURCC_strl, i );
avi_chunk_strh_t *p_strh = AVI_ChunkFind( p_strl, AVIFOURCC_strh, 0 );
if( p_strl == NULL || p_strh == NULL || p_auds == NULL || p_vids == NULL )
{
msg_Warn( p_demux, "stream[%d] incomplete", i );
+ free( tk );
continue;
}
tk->i_cat = AUDIO_ES;
tk->i_codec = AVI_FourccGetCodec( AUDIO_ES,
p_auds->p_wf->wFormatTag );
- if( tk->i_codec == VLC_FOURCC( 'v', 'o', 'r', 'b' ) )
- tk->i_blocksize = 0; /* fix vorbis VBR decoding */
- else if( ( tk->i_blocksize = p_auds->p_wf->nBlockAlign ) == 0 )
+
+ tk->i_blocksize = p_auds->p_wf->nBlockAlign;
+ if( tk->i_blocksize == 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;
- }
}
+ else if( tk->i_samplesize != 0 && tk->i_samplesize != tk->i_blocksize )
+ {
+ msg_Warn( p_demux, "track[%d] samplesize=%d and blocksize=%d are not equal."
+ "Using blocksize as a workaround.",
+ i, tk->i_samplesize, tk->i_blocksize );
+ tk->i_samplesize = tk->i_blocksize;
+ }
+
+ if( tk->i_codec == VLC_FOURCC( 'v', 'o', 'r', 'b' ) )
+ {
+ tk->i_blocksize = 0; /* fix vorbis VBR decoding */
+ }
+
es_format_Init( &fmt, AUDIO_ES, tk->i_codec );
fmt.audio.i_channels = p_auds->p_wf->nChannels;
case 24:
tk->i_codec = VLC_FOURCC('R','V','2','4');
break;
- case 16:
- /* tk->i_codec = VLC_FOURCC('R','V','1','6');*/
- /* break;*/
+ case 16: /* Yes it is RV15 */
case 15:
tk->i_codec = VLC_FOURCC('R','V','1','5');
break;
- case 9:
- tk->i_codec = VLC_FOURCC( 'Y', 'V', 'U', '9' ); /* <- TODO check that */
+ case 9: /* <- TODO check that */
+ tk->i_codec = VLC_FOURCC( 'Y', 'V', 'U', '9' );
break;
- case 8:
+ case 8: /* <- TODO check that */
tk->i_codec = VLC_FOURCC('Y','8','0','0');
break;
}
es_format_Init( &fmt, VIDEO_ES, tk->i_codec );
- if( p_vids->p_bih->biBitCount == 24 )
+ switch( tk->i_codec )
{
- /* This is in BGR format */
- fmt.video.i_bmask = 0x00ff0000;
+ case VLC_FOURCC('R','V','2','4'):
+ case VLC_FOURCC('R','V','3','2'):
+ fmt.video.i_rmask = 0x00ff0000;
fmt.video.i_gmask = 0x0000ff00;
- fmt.video.i_rmask = 0x000000ff;
+ fmt.video.i_bmask = 0x000000ff;
+ break;
+ case VLC_FOURCC('R','V','1','5'):
+ fmt.video.i_rmask = 0x7c00;
+ fmt.video.i_gmask = 0x03e0;
+ fmt.video.i_bmask = 0x001f;
+ break;
+ default:
+ break;
}
}
else
__MIN( p_vids->p_bih->biSize - sizeof( BITMAPINFOHEADER ),
p_vids->i_chunk_size - sizeof(BITMAPINFOHEADER) );
fmt.p_extra = &p_vids->p_bih[1];
- msg_Dbg( p_demux, "stream[%d] video(%4.4s) %dx%d %dbpp %ffps",
+ msg_Dbg( p_demux, "stream[%d] video(%4.4s) %"PRIu32"x%"PRIu32" %dbpp %ffps",
i, (char*)&p_vids->p_bih->biCompression,
- p_vids->p_bih->biWidth,
- p_vids->p_bih->biHeight,
+ (uint32_t)p_vids->p_bih->biWidth,
+ (uint32_t)p_vids->p_bih->biHeight,
p_vids->p_bih->biBitCount,
(float)tk->i_rate/(float)tk->i_scale );
/* Extract palette from extradata if bpp <= 8
* (assumes that extradata contains only palette but appears
* to be true for all palettized codecs we support) */
- if( fmt.i_extra && fmt.video.i_bits_per_pixel <= 8 &&
- fmt.video.i_bits_per_pixel > 0 )
+ if( fmt.video.i_bits_per_pixel > 0 && fmt.video.i_bits_per_pixel <= 8 )
{
- int i;
+ /* The palette is not always included in biSize */
+ fmt.i_extra = p_vids->i_chunk_size - sizeof(BITMAPINFOHEADER);
+ if( fmt.i_extra > 0 )
+ {
+ const uint8_t *p_pal = fmt.p_extra;
- fmt.video.p_palette = calloc( sizeof(video_palette_t), 1 );
- fmt.video.p_palette->i_entries = 1;
+ fmt.video.p_palette = calloc( 1, sizeof(video_palette_t) );
+ fmt.video.p_palette->i_entries = __MIN(fmt.i_extra/4, 256);
- /* Apparently this is necessary. But why ? */
- fmt.i_extra =
- p_vids->i_chunk_size - sizeof(BITMAPINFOHEADER);
- for( i = 0; i < __MIN(fmt.i_extra/4, 256); i++ )
- {
- ((uint32_t *)&fmt.video.p_palette->palette[0][0])[i] =
- GetDWLE((uint32_t*)fmt.p_extra + i);
+ for( int i = 0; i < fmt.video.p_palette->i_entries; i++ )
+ {
+ for( int j = 0; j < 4; j++ )
+ fmt.video.p_palette->palette[i][j] = p_pal[4*i+j];
+ }
}
}
break;
continue;
}
if( p_strn )
- {
- /* The charset of p_strn is undefined */
- EnsureUTF8( p_strn->p_str );
- fmt.psz_description = strdup( p_strn->p_str );
- }
+ fmt.psz_description = FromLatin1( p_strn->p_str );
if( tk->p_out_muxed == NULL )
tk->p_es = es_out_Add( p_demux->out, &fmt );
TAB_APPEND( p_sys->i_track, p_sys->track, tk );
(mtime_t)1000000 )
{
msg_Warn( p_demux, "broken or missing index, 'seek' will be "
- "axproximative or will have strange behaviour" );
+ "approximative or will exhibit strange behavior" );
if( i_do_index == 0 && !b_index )
{
+ if( !p_sys->b_seekable ) {
+ b_index = true;
+ goto aviindex;
+ }
int i_create;
i_create = intf_UserYesNo( p_demux, _("AVI Index") ,
_( "This AVI file is broken. Seeking will not "
if( p_sys->track[i] )
{
if( p_sys->track[i]->p_out_muxed )
- stream_DemuxDelete( p_sys->track[i]->p_out_muxed );
+ stream_Delete( p_sys->track[i]->p_out_muxed );
free( p_sys->track[i]->p_index );
free( p_sys->track[i]->p_extra );
free( p_sys->track[i] );
if( b_done )
{
- return( 1 );
+ for( i = 0; i < p_sys->i_track; i++ )
+ {
+ if( toread[i].b_ok )
+ return 1;
+ }
+ msg_Warn( p_demux, "all tracks have failed, exiting..." );
+ return 0;
}
if( i_pos == -1 )
* affect the reading speed too much. */
if( !(++i_loop_count % 1024) )
{
- if( p_demux->b_die ) return -1;
+ if( !vlc_object_alive (p_demux) ) return -1;
msleep( 10000 );
if( !(i_loop_count % (1024 * 10)) )
demux_sys_t *p_sys = p_demux->p_sys;
unsigned int i_stream;
- msg_Dbg( p_demux, "seek requested: "I64Fd" seconds %d%%",
+ msg_Dbg( p_demux, "seek requested: %"PRId64" seconds %d%%",
i_date / 1000000, i_percent );
if( p_sys->b_seekable )
i_date = AVI_GetPTS( p_stream );
/* TODO better support for i_samplesize != 0 */
- msg_Dbg( p_demux, "estimate date "I64Fd, i_date );
+ msg_Dbg( p_demux, "estimate date %"PRId64, i_date );
}
/* */
AVI_TrackSeek( p_demux, i_stream, i_date );
}
+ es_out_Control( p_demux->out, ES_OUT_SET_NEXT_DISPLAY_TIME, i_date );
p_sys->i_time = i_date;
- msg_Dbg( p_demux, "seek: "I64Fd" seconds", p_sys->i_time /1000000 );
+ msg_Dbg( p_demux, "seek: %"PRId64" seconds", p_sys->i_time /1000000 );
return VLC_SUCCESS;
}
else
for( ;; )
{
- if( p_demux->b_die ) return VLC_EGENERIC;
+ if( !vlc_object_alive (p_demux) ) return VLC_EGENERIC;
if( AVI_PacketGetHeader( p_demux, &avi_pk ) )
{
* affect the reading speed too much. */
if( !(++i_loop_count % 1024) )
{
- if( p_demux->b_die ) return VLC_EGENERIC;
+ if( !vlc_object_alive (p_demux) ) return VLC_EGENERIC;
msleep( 10000 );
if( !(i_loop_count % (1024 * 10)) )
}
msg_Dbg( p_demux,
- "old:"I64Fd" %s new "I64Fd,
+ "old:%"PRId64" %s new %"PRId64,
i_oldpts,
i_oldpts > i_date ? ">" : "<",
i_date );
return VLC_EGENERIC;
}
}
- if( p_stream->p_es )
- es_out_Control( p_demux->out, ES_OUT_SET_NEXT_DISPLAY_TIME, p_stream->p_es, i_date );
}
#if 0
else
break;
case AVITWOCC_dc:
case AVITWOCC_db:
+ case AVITWOCC_AC:
SET_PTR( pi_type, VIDEO_ES );
break;
default:
* this code is called only on broken files). */
if( !(++i_count % 1024) )
{
- if( p_demux->b_die ) return VLC_EGENERIC;
+ if( !vlc_object_alive (p_demux) ) return VLC_EGENERIC;
msleep( 10000 );
if( !(i_count % (1024 * 10)) )
{
demux_sys_t *p_sys = p_demux->p_sys;
- avi_chunk_list_t *p_riff;
- avi_chunk_list_t *p_movi;
+ avi_chunk_list_t *p_riff;
+ avi_chunk_list_t *p_movi;
unsigned int i_stream;
off_t i_movi_end;
+ mtime_t i_dialog_update;
+ int i_dialog_id;
+
p_riff = AVI_ChunkFind( &p_sys->ck_root, AVIFOURCC_RIFF, 0);
p_movi = AVI_ChunkFind( p_riff, AVIFOURCC_movi, 0);
/* Only show dialog if AVI is > 10MB */
- p_demux->p_sys->i_dialog_id = -1;
+ i_dialog_id = -1;
+ i_dialog_update = mdate();
if( stream_Size( p_demux->s ) > 10000000 )
- {
- p_demux->p_sys->i_dialog_id = intf_IntfProgress( p_demux,
- _( "Fixing AVI Index..." ),
- 0.0 );
- p_demux->p_sys->last_update = mdate();
- }
+ i_dialog_id = intf_IntfProgress( p_demux, _("Fixing AVI Index..."), 0.0 );
for( ;; )
{
avi_packet_t pk;
- if( p_demux->b_die )
- {
- return;
- }
+ if( !vlc_object_alive (p_demux) )
+ break;
- /* Don't update dialog too often */
- if( p_demux->p_sys->i_dialog_id > 0 &&
- mdate() - p_demux->p_sys->last_update > 100000 )
+ /* Don't update/check dialog too often */
+ if( i_dialog_id > 0 && mdate() - i_dialog_update > 100000 )
{
- int64_t i_pos = stream_Tell( p_demux->s )* 100 /
- stream_Size( p_demux->s );
- float f_pos = (float)i_pos;
- p_demux->p_sys->last_update = mdate();
- intf_ProgressUpdate( p_demux, p_demux->p_sys->i_dialog_id,
+ if( intf_ProgressIsCancelled( p_demux, i_dialog_id ) )
+ break;
+
+ double f_pos = 100.0 * stream_Tell( p_demux->s ) /
+ stream_Size( p_demux->s );
+ intf_ProgressUpdate( p_demux, i_dialog_id,
_( "Fixing AVI Index..." ), f_pos, -1 );
+
+ i_dialog_update = mdate();
}
if( AVI_PacketGetHeader( p_demux, &pk ) )
- {
break;
- }
+
if( pk.i_stream < p_sys->i_track &&
pk.i_cat == p_sys->track[pk.i_stream]->i_cat )
{
{
switch( pk.i_fourcc )
{
- case AVIFOURCC_idx1:
- if( p_sys->b_odml )
- {
- avi_chunk_list_t *p_sysx;
- p_sysx = AVI_ChunkFind( &p_sys->ck_root,
- AVIFOURCC_RIFF, 1 );
+ case AVIFOURCC_idx1:
+ if( p_sys->b_odml )
+ {
+ avi_chunk_list_t *p_sysx;
+ p_sysx = AVI_ChunkFind( &p_sys->ck_root,
+ AVIFOURCC_RIFF, 1 );
- msg_Dbg( p_demux, "looking for new RIFF chunk" );
- if( stream_Seek( p_demux->s, p_sysx->i_chunk_pos + 24))
- {
- goto print_stat;
- }
- break;
- }
- goto print_stat;
- case AVIFOURCC_RIFF:
- msg_Dbg( p_demux, "new RIFF chunk found" );
- case AVIFOURCC_rec:
- case AVIFOURCC_JUNK:
- break;
- default:
- msg_Warn( p_demux, "need resync, probably broken avi" );
- if( AVI_PacketSearch( p_demux ) )
- {
- msg_Warn( p_demux, "lost sync, abord index creation" );
+ msg_Dbg( p_demux, "looking for new RIFF chunk" );
+ if( stream_Seek( p_demux->s, p_sysx->i_chunk_pos + 24 ) )
goto print_stat;
- }
+ break;
+ }
+ goto print_stat;
+
+ case AVIFOURCC_RIFF:
+ msg_Dbg( p_demux, "new RIFF chunk found" );
+ break;
+
+ case AVIFOURCC_rec:
+ case AVIFOURCC_JUNK:
+ break;
+
+ default:
+ msg_Warn( p_demux, "need resync, probably broken avi" );
+ if( AVI_PacketSearch( p_demux ) )
+ {
+ msg_Warn( p_demux, "lost sync, abord index creation" );
+ goto print_stat;
+ }
}
}
}
print_stat:
- if( p_demux->p_sys->i_dialog_id > 0 )
- {
- intf_UserHide( p_demux, p_demux->p_sys->i_dialog_id );
- }
+ if( i_dialog_id > 0 )
+ intf_UserHide( p_demux, i_dialog_id );
for( i_stream = 0; i_stream < p_sys->i_track; i_stream++ )
{
- msg_Dbg( p_demux,
- "stream[%d] creating %d index entries",
- i_stream,
- p_sys->track[i_stream]->i_idxnb );
+ msg_Dbg( p_demux, "stream[%d] creating %d index entries",
+ i_stream, p_sys->track[i_stream]->i_idxnb );
}
}
i_length /= (mtime_t)1000000; /* in seconds */
msg_Dbg( p_demux,
- "stream[%d] length:"I64Fd" (based on index)",
+ "stream[%d] length:%"PRId64" (based on index)",
i,
i_length );
i_maxlength = __MAX( i_maxlength, i_length );