#include <vlc_plugin.h>
#include <vlc_demux.h>
-#include <vlc_interface.h>
+#include <vlc_dialog.h>
#include <vlc_meta.h>
#include <vlc_codecs.h>
static const char *const ppsz_indexes[] = { N_("Ask"), N_("Always fix"),
N_("Never fix") };
-vlc_module_begin();
- set_shortname( "AVI" );
- set_description( N_("AVI demuxer") );
- set_capability( "demux", 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
uint32_t i_flags;
off_t i_pos;
uint32_t i_length;
- uint32_t i_lengthtotal;
+ int64_t i_lengthtotal;
} avi_entry_t;
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 );
}
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_CODEC_VORBIS )
+ {
+ 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;
* - Size of the next packet, and so on ...
*/
- if( tk->i_codec == VLC_FOURCC( 'v', 'o', 'r', 'b' ) )
+ if( tk->i_codec == VLC_CODEC_VORBIS )
{
uint8_t *p_extra = fmt.p_extra;
size_t i_extra = fmt.i_extra;
tk->i_cat = VIDEO_ES;
tk->i_codec = AVI_FourccGetCodec( VIDEO_ES,
p_vids->p_bih->biCompression );
- if( p_vids->p_bih->biCompression == 0x00 )
+ if( p_vids->p_bih->biCompression == VLC_FOURCC( 'D', 'X', 'S', 'B' ) )
+ {
+ msg_Dbg( p_demux, "stream[%d] subtitles", i );
+ es_format_Init( &fmt, SPU_ES, p_vids->p_bih->biCompression );
+ break;
+ }
+ else if( p_vids->p_bih->biCompression == 0x00 )
{
switch( p_vids->p_bih->biBitCount )
{
case 32:
- tk->i_codec = VLC_FOURCC('R','V','3','2');
+ tk->i_codec = VLC_CODEC_RGB32;
break;
case 24:
- tk->i_codec = VLC_FOURCC('R','V','2','4');
+ tk->i_codec = VLC_CODEC_RGB24;
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');
+ tk->i_codec = VLC_CODEC_RGB15;
break;
- case 9:
- tk->i_codec = VLC_FOURCC( 'Y', 'V', 'U', '9' ); /* <- TODO check that */
+ case 9: /* <- TODO check that */
+ tk->i_codec = VLC_CODEC_I410;
break;
- case 8:
- tk->i_codec = VLC_FOURCC('Y','8','0','0');
+ case 8: /* <- TODO check that */
+ tk->i_codec = VLC_CODEC_GREY;
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_CODEC_RGB24:
+ case VLC_CODEC_RGB32:
+ fmt.video.i_rmask = 0x00ff0000;
fmt.video.i_gmask = 0x0000ff00;
- fmt.video.i_rmask = 0x000000ff;
+ fmt.video.i_bmask = 0x000000ff;
+ break;
+ case VLC_CODEC_RGB15:
+ fmt.video.i_rmask = 0x7c00;
+ fmt.video.i_gmask = 0x03e0;
+ fmt.video.i_bmask = 0x001f;
+ break;
+ default:
+ break;
}
}
else
{
es_format_Init( &fmt, VIDEO_ES, p_vids->p_bih->biCompression );
- if( tk->i_codec == FOURCC_mp4v &&
+ if( tk->i_codec == VLC_CODEC_MP4V &&
!strncasecmp( (char*)&p_strh->i_handler, "XVID", 4 ) )
{
- fmt.i_codec = VLC_FOURCC( 'X', 'V', 'I', 'D' );
+ fmt.i_codec =
+ fmt.i_original_fourcc = VLC_FOURCC( 'X', 'V', 'I', 'D' );
}
}
tk->i_samplesize = 0;
/* 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;
case( AVIFOURCC_txts):
tk->i_cat = SPU_ES;
- tk->i_codec = VLC_FOURCC( 's', 'u', 'b', 't' );
+ tk->i_codec = VLC_CODEC_SUBT;
msg_Dbg( p_demux, "stream[%d] subtitles", i );
es_format_Init( &fmt, SPU_ES, tk->i_codec );
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 );
b_index = true;
goto aviindex;
}
- int i_create;
- i_create = intf_UserYesNo( p_demux, _("AVI Index") ,
- _( "This AVI file is broken. Seeking will not "
- "work correctly.\nDo you want to "
- "try to repair it?\n\nThis might take a long time." ),
- _( "Repair" ), _( "Don't repair" ), _( "Cancel") );
- if( i_create == DIALOG_OK_YES )
- {
- b_index = true;
- msg_Dbg( p_demux, "Fixing AVI index" );
- goto aviindex;
- }
- else if( i_create == DIALOG_CANCELLED )
+ switch( dialog_Question( p_demux, _("AVI Index") ,
+ _( "This AVI file is broken. Seeking will not work correctly.\n"
+ "Do you want to try to fix it?\n\n"
+ "This might take a long time." ),
+ _( "Repair" ), _( "Don't repair" ), _( "Cancel") ) )
{
- /* Kill input */
- vlc_object_kill( p_demux->p_parent );
- goto error;
+ case 1:
+ b_index = true;
+ msg_Dbg( p_demux, "Fixing AVI index" );
+ goto aviindex;
+ case 3:
+ /* Kill input */
+ vlc_object_kill( p_demux->p_parent );
+ goto error;
}
}
}
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 )
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: %"PRId64" seconds", p_sys->i_time /1000000 );
return VLC_SUCCESS;
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
{
switch( i_fourcc )
{
- case FOURCC_DIV1:
+ case VLC_CODEC_DIV1:
/* we have:
* startcode: 0x00000100 32bits
* framenumber ? 5bits
}
return p_byte[4] & 0x06 ? 0 : AVIIF_KEYFRAME;
- case FOURCC_DIV2:
- case FOURCC_DIV3: /* wmv1 also */
+ case VLC_CODEC_DIV2:
+ case VLC_CODEC_DIV3:
+ case VLC_CODEC_WMV1:
/* we have
* picture type 0(I),1(P) 2bits
*/
return p_byte[0] & 0xC0 ? 0 : AVIIF_KEYFRAME;
- case FOURCC_mp4v:
+ case VLC_CODEC_MP4V:
/* we should find first occurrence of 0x000001b6 (32bits)
* startcode: 0x000001b6 32bits
* piture type 0(I),1(P) 2bits
case AUDIO_ES:
wf_tag_to_fourcc( i_codec, &i_codec, NULL );
return i_codec;
-
case VIDEO_ES:
- /* XXX DIV1 <- msmpeg4v1, DIV2 <- msmpeg4v2, DIV3 <- msmpeg4v3, mp4v for mpeg4 */
- switch( i_codec )
- {
- case FOURCC_1:
- return VLC_FOURCC('m','r','l','e');
- case FOURCC_DIV1:
- case FOURCC_div1:
- case FOURCC_MPG4:
- case FOURCC_mpg4:
- return FOURCC_DIV1;
- case FOURCC_DIV2:
- case FOURCC_div2:
- case FOURCC_MP42:
- case FOURCC_mp42:
- case FOURCC_MPG3:
- case FOURCC_mpg3:
- return FOURCC_DIV2;
- case FOURCC_div3:
- case FOURCC_MP43:
- case FOURCC_mp43:
- case FOURCC_DIV3:
- case FOURCC_DIV4:
- case FOURCC_div4:
- case FOURCC_DIV5:
- case FOURCC_div5:
- case FOURCC_DIV6:
- case FOURCC_div6:
- case FOURCC_AP41:
- case FOURCC_3IV1:
- case FOURCC_3iv1:
- case FOURCC_3IVD:
- case FOURCC_3ivd:
- case FOURCC_3VID:
- case FOURCC_3vid:
- return FOURCC_DIV3;
- case FOURCC_DIVX:
- case FOURCC_divx:
- case FOURCC_MP4S:
- case FOURCC_mp4s:
- case FOURCC_M4S2:
- case FOURCC_m4s2:
- case FOURCC_xvid:
- case FOURCC_XVID:
- case FOURCC_XviD:
- case FOURCC_DX50:
- case FOURCC_dx50:
- case FOURCC_mp4v:
- case FOURCC_4:
- case FOURCC_3IV2:
- case FOURCC_3iv2:
- return FOURCC_mp4v;
- }
+ return vlc_fourcc_GetCodec( i_cat, i_codec );
default:
return VLC_FOURCC( 'u', 'n', 'd', 'f' );
}
break;
case AVITWOCC_dc:
case AVITWOCC_db:
+ case AVITWOCC_AC:
SET_PTR( pi_type, VIDEO_ES );
break;
default:
off_t i_movi_end;
mtime_t i_dialog_update;
- int i_dialog_id;
+ dialog_progress_bar_t *p_dialog = NULL;
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 */
- i_dialog_id = -1;
+ i_dialog_update = mdate();
if( stream_Size( p_demux->s ) > 10000000 )
- {
- i_dialog_id = intf_IntfProgress( p_demux,
- _( "Fixing AVI Index..." ),
- 0.0 );
- i_dialog_update = mdate();
- }
+ p_dialog = dialog_ProgressCreate( p_demux, _("Fixing AVI Index..."),
+ NULL, _("Cancel") );
for( ;; )
{
break;
/* Don't update/check dialog too often */
- if( i_dialog_id > 0 && mdate() - i_dialog_update > 100000 )
+ if( p_dialog && mdate() - i_dialog_update > 100000 )
{
- if( intf_ProgressIsCancelled( p_demux, i_dialog_id ) )
+ if( dialog_ProgressCancelled( p_dialog ) )
break;
- int64_t i_pos = stream_Tell( p_demux->s )* 100 /
- stream_Size( p_demux->s );
- float f_pos = (float)i_pos;
+ float f_pos = (float)stream_Tell( p_demux->s ) /
+ (float)stream_Size( p_demux->s );
+ dialog_ProgressSet( p_dialog, NULL, f_pos );
+
i_dialog_update = mdate();
- intf_ProgressUpdate( p_demux, i_dialog_id,
- _( "Fixing AVI Index..." ), f_pos, -1 );
}
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( i_dialog_id > 0 )
- {
- intf_UserHide( p_demux, i_dialog_id );
- }
+ if( p_dialog != NULL )
+ dialog_ProgressDestroy( p_dialog );
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 );
}
}