Commit b3a658e6 authored by Laurent Aimar's avatar Laurent Aimar

Improved support for AVI with DV data type 1.

It closes #4585.
parent 47b27a1e
...@@ -43,6 +43,7 @@ ...@@ -43,6 +43,7 @@
#include <vlc_memory.h> #include <vlc_memory.h>
#include "libavi.h" #include "libavi.h"
#include "../rawdv.h"
/***************************************************************************** /*****************************************************************************
* Module descriptor * Module descriptor
...@@ -148,6 +149,9 @@ typedef struct ...@@ -148,6 +149,9 @@ typedef struct
es_out_id_t *p_es; es_out_id_t *p_es;
int i_dv_audio_rate;
es_out_id_t *p_es_dv_audio;
/* Avi Index */ /* Avi Index */
avi_index_t idx; avi_index_t idx;
...@@ -158,8 +162,6 @@ typedef struct ...@@ -158,8 +162,6 @@ typedef struct
unsigned int i_blockno; unsigned int i_blockno;
unsigned int i_blocksize; unsigned int i_blocksize;
/* For muxed streams */
stream_t *p_out_muxed;
} avi_track_t; } avi_track_t;
struct demux_sys_t struct demux_sys_t
...@@ -168,7 +170,6 @@ struct demux_sys_t ...@@ -168,7 +170,6 @@ struct demux_sys_t
mtime_t i_length; mtime_t i_length;
bool b_seekable; bool b_seekable;
bool b_muxed;
avi_chunk_t ck_root; avi_chunk_t ck_root;
bool b_odml; bool b_odml;
...@@ -217,6 +218,8 @@ static void AVI_IndexCreate ( demux_t * ); ...@@ -217,6 +218,8 @@ static void AVI_IndexCreate ( demux_t * );
static void AVI_ExtractSubtitle( demux_t *, unsigned int i_stream, avi_chunk_list_t *, avi_chunk_STRING_t * ); static void AVI_ExtractSubtitle( demux_t *, unsigned int i_stream, avi_chunk_list_t *, avi_chunk_STRING_t * );
static void AVI_DvHandleAudio( demux_t *, avi_track_t *, block_t * );
static mtime_t AVI_MovieGetLength( demux_t * ); static mtime_t AVI_MovieGetLength( demux_t * );
static void AVI_MetaLoad( demux_t *, avi_chunk_list_t *p_riff, avi_chunk_avih_t *p_avih ); static void AVI_MetaLoad( demux_t *, avi_chunk_list_t *p_riff, avi_chunk_avih_t *p_avih );
...@@ -279,7 +282,6 @@ static int Open( vlc_object_t * p_this ) ...@@ -279,7 +282,6 @@ static int Open( vlc_object_t * p_this )
p_sys->i_length = 0; p_sys->i_length = 0;
p_sys->i_movi_lastchunk_pos = 0; p_sys->i_movi_lastchunk_pos = 0;
p_sys->b_odml = false; p_sys->b_odml = false;
p_sys->b_muxed = false;
p_sys->i_track = 0; p_sys->i_track = 0;
p_sys->track = NULL; p_sys->track = NULL;
p_sys->meta = NULL; p_sys->meta = NULL;
...@@ -597,21 +599,16 @@ static int Open( vlc_object_t * p_this ) ...@@ -597,21 +599,16 @@ static int Open( vlc_object_t * p_this )
case( AVIFOURCC_iavs): case( AVIFOURCC_iavs):
case( AVIFOURCC_ivas): case( AVIFOURCC_ivas):
p_sys->b_muxed = true;
msg_Dbg( p_demux, "stream[%d] iavs with handler %4.4s", i, (char *)&p_strh->i_handler ); msg_Dbg( p_demux, "stream[%d] iavs with handler %4.4s", i, (char *)&p_strh->i_handler );
if( p_strh->i_handler == FOURCC_dvsd || tk->i_cat = VIDEO_ES;
p_strh->i_handler == FOURCC_dvhd || tk->i_codec = AVI_FourccGetCodec( VIDEO_ES, p_strh->i_handler );
p_strh->i_handler == FOURCC_dvsl || tk->i_samplesize = 0;
p_strh->i_handler == FOURCC_dv25 || tk->i_dv_audio_rate = tk->i_codec == VLC_CODEC_DV ? -1 : 0;
p_strh->i_handler == FOURCC_dv50 )
{ es_format_Init( &fmt, VIDEO_ES, p_strh->i_handler );
tk->p_out_muxed = stream_DemuxNew( p_demux, (char *)"rawdv", p_demux->out ); fmt.video.i_width = p_avih->i_width;
if( !tk->p_out_muxed ) fmt.video.i_height = p_avih->i_height;
msg_Err( p_demux, "could not load the DV parser" ); break;
else break;
}
free( tk );
continue;
case( AVIFOURCC_mids): case( AVIFOURCC_mids):
msg_Dbg( p_demux, "stream[%d] midi is UNSUPPORTED", i ); msg_Dbg( p_demux, "stream[%d] midi is UNSUPPORTED", i );
...@@ -623,13 +620,9 @@ static int Open( vlc_object_t * p_this ) ...@@ -623,13 +620,9 @@ static int Open( vlc_object_t * p_this )
} }
if( p_strn ) if( p_strn )
fmt.psz_description = FromACP( p_strn->p_str ); fmt.psz_description = FromACP( p_strn->p_str );
if( tk->p_out_muxed == NULL ) tk->p_es = es_out_Add( p_demux->out, &fmt );
tk->p_es = es_out_Add( p_demux->out, &fmt );
TAB_APPEND( p_sys->i_track, p_sys->track, tk ); TAB_APPEND( p_sys->i_track, p_sys->track, tk );
if(!p_sys->b_muxed ) es_format_Clean( &fmt );
{
es_format_Clean( &fmt );
}
} }
if( p_sys->i_track <= 0 ) if( p_sys->i_track <= 0 )
...@@ -793,8 +786,6 @@ static void Close ( vlc_object_t * p_this ) ...@@ -793,8 +786,6 @@ static void Close ( vlc_object_t * p_this )
{ {
if( p_sys->track[i] ) if( p_sys->track[i] )
{ {
if( p_sys->track[i]->p_out_muxed )
stream_Delete( p_sys->track[i]->p_out_muxed );
avi_index_Clean( &p_sys->track[i]->idx ); avi_index_Clean( &p_sys->track[i]->idx );
free( p_sys->track[i] ); free( p_sys->track[i] );
} }
...@@ -843,14 +834,13 @@ static int Demux_Seekable( demux_t *p_demux ) ...@@ -843,14 +834,13 @@ static int Demux_Seekable( demux_t *p_demux )
avi_track_t *tk = p_sys->track[i_track]; avi_track_t *tk = p_sys->track[i_track];
bool b; bool b;
if( p_sys->b_muxed && tk->p_out_muxed ) es_out_Control( p_demux->out, ES_OUT_GET_ES_STATE, tk->p_es, &b );
if( tk->p_es_dv_audio )
{ {
i_track_count++; bool b_extra;
tk->b_activated = true; es_out_Control( p_demux->out, ES_OUT_GET_ES_STATE, tk->p_es_dv_audio, &b_extra );
continue; b |= b_extra;
} }
es_out_Control( p_demux->out, ES_OUT_GET_ES_STATE, tk->p_es, &b );
if( b && !tk->b_activated ) if( b && !tk->b_activated )
{ {
if( p_sys->b_seekable) if( p_sys->b_seekable)
...@@ -1171,10 +1161,9 @@ static int Demux_Seekable( demux_t *p_demux ) ...@@ -1171,10 +1161,9 @@ static int Demux_Seekable( demux_t *p_demux )
} }
//p_pes->i_rate = p_demux->stream.control.i_rate; //p_pes->i_rate = p_demux->stream.control.i_rate;
if( tk->p_out_muxed ) if( tk->i_dv_audio_rate )
stream_DemuxSend( tk->p_out_muxed, p_frame ); AVI_DvHandleAudio( p_demux, tk, p_frame );
else es_out_Send( p_demux->out, tk->p_es, p_frame );
es_out_Send( p_demux->out, tk->p_es, p_frame );
} }
} }
...@@ -1191,12 +1180,6 @@ static int Demux_UnSeekable( demux_t *p_demux ) ...@@ -1191,12 +1180,6 @@ static int Demux_UnSeekable( demux_t *p_demux )
unsigned int i_stream; unsigned int i_stream;
unsigned int i_packet; unsigned int i_packet;
if( p_sys->b_muxed )
{
msg_Err( p_demux, "Can not yet process muxed avi substreams without seeking" );
return VLC_EGENERIC;
}
es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_sys->i_time + 1 ); es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_sys->i_time + 1 );
/* *** find master stream for data packet skipping algo *** */ /* *** find master stream for data packet skipping algo *** */
...@@ -1207,6 +1190,12 @@ static int Demux_UnSeekable( demux_t *p_demux ) ...@@ -1207,6 +1190,12 @@ static int Demux_UnSeekable( demux_t *p_demux )
bool b; bool b;
es_out_Control( p_demux->out, ES_OUT_GET_ES_STATE, tk->p_es, &b ); es_out_Control( p_demux->out, ES_OUT_GET_ES_STATE, tk->p_es, &b );
if( tk->p_es_dv_audio )
{
bool b_extra;
es_out_Control( p_demux->out, ES_OUT_GET_ES_STATE, tk->p_es_dv_audio, &b_extra );
b |= b_extra;
}
if( b && tk->i_cat == VIDEO_ES ) if( b && tk->i_cat == VIDEO_ES )
{ {
...@@ -1289,6 +1278,8 @@ static int Demux_UnSeekable( demux_t *p_demux ) ...@@ -1289,6 +1278,8 @@ static int Demux_UnSeekable( demux_t *p_demux )
} }
//p_pes->i_rate = p_demux->stream.control.i_rate; //p_pes->i_rate = p_demux->stream.control.i_rate;
if( p_stream->i_dv_audio_rate )
AVI_DvHandleAudio( p_demux, p_stream, p_frame );
es_out_Send( p_demux->out, p_stream->p_es, p_frame ); es_out_Send( p_demux->out, p_stream->p_es, p_frame );
} }
else else
...@@ -2594,6 +2585,34 @@ static void AVI_MetaLoad( demux_t *p_demux, ...@@ -2594,6 +2585,34 @@ static void AVI_MetaLoad( demux_t *p_demux,
} }
} }
static void AVI_DvHandleAudio( demux_t *p_demux, avi_track_t *tk, block_t *p_frame )
{
size_t i_offset = 80*6+80*16*3 + 3;
if( p_frame->i_buffer < i_offset + 5 )
return;
if( p_frame->p_buffer[i_offset] != 0x50 )
return;
es_format_t fmt;
dv_get_audio_format( &fmt, &p_frame->p_buffer[i_offset + 1] );
if( tk->p_es_dv_audio && tk->i_dv_audio_rate != fmt.audio.i_rate )
{
es_out_Del( p_demux->out, tk->p_es_dv_audio );
tk->p_es_dv_audio = es_out_Add( p_demux->out, &fmt );
}
else if( !tk->p_es_dv_audio )
{
tk->p_es_dv_audio = es_out_Add( p_demux->out, &fmt );
}
tk->i_dv_audio_rate = fmt.audio.i_rate;
block_t *p_frame_audio = dv_extract_audio( p_frame );
if( p_frame_audio )
es_out_Send( p_demux->out, tk->p_es_dv_audio, p_frame_audio );
}
/***************************************************************************** /*****************************************************************************
* Subtitles * Subtitles
*****************************************************************************/ *****************************************************************************/
......
...@@ -416,6 +416,10 @@ static int AVI_ChunkRead_strf( stream_t *s, avi_chunk_t *p_chk ) ...@@ -416,6 +416,10 @@ static int AVI_ChunkRead_strf( stream_t *s, avi_chunk_t *p_chk )
p_chk->strf.vids.p_bih->biBitCount ); p_chk->strf.vids.p_bih->biBitCount );
#endif #endif
break; break;
case AVIFOURCC_iavs:
case AVIFOURCC_ivas:
p_chk->strf.common.i_cat = UNKNOWN_ES;
break;
case( AVIFOURCC_txts ): case( AVIFOURCC_txts ):
p_chk->strf.common.i_cat = SPU_ES; p_chk->strf.common.i_cat = SPU_ES;
break; break;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment