* avi: respect frame size (for audio codec) and close bug 75.
* ffmpeg: can now read multiples audio frames from the same buffer.
* audio.c: audio decoder using ffmpeg library
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
- * $Id: audio.c,v 1.11 2003/01/07 21:49:01 fenrir Exp $
+ * $Id: audio.c,v 1.12 2003/01/11 18:10:49 fenrir Exp $
*
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
*
p_adec->p_context->block_align = p_adec->format.i_blockalign;
#endif
p_adec->p_context->bit_rate = p_adec->format.i_avgbytespersec * 8;
-
+
if( ( p_adec->p_context->extradata_size = p_adec->format.i_size ) > 0 )
{
p_adec->p_context->extradata =
p_adec->format.p_data,
p_adec->format.i_size );
}
-
+
/* ***** Open the codec ***** */
if (avcodec_open(p_adec->p_context, p_adec->p_codec) < 0)
{
- msg_Err( p_adec->p_fifo,
+ msg_Err( p_adec->p_fifo,
"cannot open codec (%s)",
p_adec->psz_namecodec );
return( -1 );
}
else
{
- msg_Dbg( p_adec->p_fifo,
+ msg_Dbg( p_adec->p_fifo,
"ffmpeg codec (%s) started",
p_adec->psz_namecodec );
}
- p_adec->p_output = malloc( AVCODEC_MAX_AUDIO_FRAME_SIZE );
-
+ p_adec->p_output = malloc( AVCODEC_MAX_AUDIO_FRAME_SIZE );
+
p_adec->output_format.i_format = AOUT_FMT_S16_NE;
p_adec->output_format.i_rate = p_adec->format.i_samplespersec;
p_adec->output_format.i_physical_channels
= p_adec->output_format.i_original_channels
= p_adec->format.i_nb_channels;
-
+
p_adec->p_aout = NULL;
p_adec->p_aout_input = NULL;
-
+
return( 0 );
}
int i_samplesperchannel;
int i_output_size;
int i_frame_size;
- int i_status;
+ int i_used;
do
{
if( i_frame_size > 0 )
{
- if( p_adec->i_buffer_size < i_frame_size + 16 )
+ uint8_t *p_last;
+ int i_need;
+
+
+ i_need = i_frame_size + 16 + p_adec->i_buffer;
+ if( p_adec->i_buffer_size < i_need )
{
- FREE( p_adec->p_buffer );
- p_adec->p_buffer = malloc( i_frame_size + 16 );
- p_adec->i_buffer_size = i_frame_size + 16;
+ p_last = p_adec->p_buffer;
+ p_adec->p_buffer = malloc( i_need );
+ p_adec->i_buffer_size = i_need;
+ if( p_adec->i_buffer > 0 )
+ {
+ memcpy( p_adec->p_buffer, p_last, p_adec->i_buffer );
+ }
+ FREE( p_last );
}
-
- E_( GetPESData )( p_adec->p_buffer, p_adec->i_buffer_size, p_pes );
+ i_frame_size =
+ E_( GetPESData )( p_adec->p_buffer + p_adec->i_buffer,
+ i_frame_size,
+ p_pes );
+ /* make ffmpeg happier but I'm not sure it's needed for audio */
+ memset( p_adec->p_buffer + p_adec->i_buffer + i_frame_size,
+ 0,
+ 16 );
}
input_DeletePES( p_adec->p_fifo->p_packets_mgt, p_pes );
} while( i_frame_size <= 0 );
-
- i_status = avcodec_decode_audio( p_adec->p_context,
- (s16*)p_adec->p_output,
- &i_output_size,
- p_adec->p_buffer,
- i_frame_size );
- if( i_status < 0 )
+
+ i_frame_size += p_adec->i_buffer;
+
+usenextdata:
+ i_used = avcodec_decode_audio( p_adec->p_context,
+ (int16_t*)p_adec->p_output,
+ &i_output_size,
+ p_adec->p_buffer,
+ i_frame_size );
+ if( i_used < 0 )
{
- msg_Warn( p_adec->p_fifo,
+ msg_Warn( p_adec->p_fifo,
"cannot decode one frame (%d bytes)",
i_frame_size );
+ p_adec->i_buffer = 0;
return;
}
+ else if( i_used < i_frame_size )
+ {
+ memmove( p_adec->p_buffer,
+ p_adec->p_buffer + i_used,
+ p_adec->i_buffer_size - i_used );
+
+ p_adec->i_buffer = i_frame_size - i_used;
+ }
+ else
+ {
+ p_adec->i_buffer = 0;
+ }
+ i_frame_size -= i_used;
+
+// msg_Dbg( p_adec->p_fifo, "frame size:%d buffer used:%d", i_frame_size, i_used );
if( i_output_size <= 0 )
{
msg_Warn( p_adec->p_fifo,
msg_Err( p_adec->p_fifo, "cannot create aout" );
return;
}
-
+
if( p_adec->pts != 0 && p_adec->pts != aout_DateGet( &p_adec->date ) )
{
aout_DateSet( &p_adec->date, p_adec->pts );
p_aout_buffer->i_nb_bytes );
aout_DecPlay( p_adec->p_aout, p_adec->p_aout_input, p_aout_buffer );
-
+
+ if( i_frame_size > 0 )
+ {
+ goto usenextdata;
+ }
+
return;
}
* asf.c : ASFv01 file input module for vlc
*****************************************************************************
* Copyright (C) 2001 VideoLAN
- * $Id: asf.c,v 1.14 2003/01/07 21:49:01 fenrir Exp $
+ * $Id: asf.c,v 1.15 2003/01/11 18:10:49 fenrir Exp $
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
*
* This program is free software; you can redistribute it and/or modify
mtime_t i_pts;
mtime_t i_pts_delta;
+ if( i_skip >= i_packet_size_left )
+ {
+ /* prevent some segfault with invalid file */
+ break;
+ }
+
i_stream_number = p_peek[i_skip] & 0x7f;
i_skip++;
* avi.c : AVI file Stream input module for vlc
*****************************************************************************
* Copyright (C) 2001 VideoLAN
- * $Id: avi.c,v 1.21 2003/01/09 18:23:43 fenrir Exp $
+ * $Id: avi.c,v 1.22 2003/01/11 18:10:49 fenrir Exp $
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
*
* This program is free software; you can redistribute it and/or modify
i_read = input_SplitBuffer(p_input,
&p_data,
__MIN( i_size -
- p_pes->i_pes_size, 1024 ) );
+ p_pes->i_pes_size, 2048 ) );
if( i_read <= 0 )
{
return p_pes->i_pes_size;
}
/* *** movie length in sec *** */
-#if 0
- p_avi->i_length = (mtime_t)p_avih->i_totalframes *
- (mtime_t)p_avih->i_microsecperframe /
- (mtime_t)1000000;
-#endif
-
p_avi->i_length = AVI_MovieGetLength( p_input, p_avi );
if( p_avi->i_length < (mtime_t)p_avih->i_totalframes *
(mtime_t)p_avih->i_microsecperframe /
mtime_t i_pts )
{
return (mtime_t)((int64_t)i_pts *
- (int64_t)p_info->i_samplesize *
(int64_t)p_info->i_rate /
(int64_t)p_info->i_scale /
- (int64_t)1000000 );
-
+ (int64_t)1000000 *
+ (int64_t)p_info->i_samplesize );
}
static mtime_t AVI_GetDPTS( avi_stream_t *p_stream, int i_count )
}
}
+#if 0
+static pes_packet_t *PES_split( input_thread_t *p_input, avi_stream_t *p_stream, pes_packet_t *p_pes )
+{
+ pes_packet_t *p_pes2;
+ data_packet_t *p_data;
+ int i_nb_data;
+
+ if( p_pes->i_nb_data < 2 )
+ {
+ return( NULL );
+ }
+ p_pes2 = input_NewPES( p_input->p_method_data );
+ p_pes2->i_pts = p_pes->i_pts;
+ p_pes2->i_dts = p_pes->i_dts;
+ p_pes2->i_nb_data = p_pes->i_nb_data/2;
+ p_pes2->i_pes_size = 0;
+ for( i_nb_data = 0, p_data = p_pes->p_first;
+ i_nb_data < p_pes2->i_nb_data;
+ i_nb_data++, p_data = p_data->p_next )
+ {
+ p_pes2->i_pes_size +=
+ p_data->p_payload_end - p_data->p_payload_start;
+ p_pes2->p_last = p_data;
+ }
+ p_pes2->p_first = p_pes->p_first;
+ p_pes2->p_last->p_next = NULL;
+
+ p_pes->p_first = p_data;
+ p_pes->i_pes_size -= p_pes2->i_pes_size;
+ p_pes->i_nb_data -= p_pes2->i_nb_data;
+// p_pes->i_pts += AVI_GetDPTS( p_stream, p_pes2->i_pes_size );
+// p_pes->i_dts += AVI_GetDPTS( p_stream, p_pes2->i_pes_size );
+ p_pes->i_pts = 0;
+ p_pes->i_dts = 0;
+ return( p_pes2 );
+}
+#endif
+
/*****************************************************************************
* AVIDemux_Seekable: reads and demuxes data packets for stream seekable
*****************************************************************************
{
i_size = __MIN( p_stream->p_index[p_stream->i_idxposc].i_length -
p_stream->i_idxposb,
-// 100 * 1024 ); // 10Ko max
- __MAX( toread[i_stream].i_toread, 128 ) );
- // 128 is to avoid infinit loop
+ __MAX( toread[i_stream].i_toread,
+ p_stream->i_samplesize ) );
}
else
{
input_ClockGetTS( p_input,
p_input->stream.p_selected_program,
p_pes->i_pts * 9/100);
+#if 0
+ /* debuuging: split pes in 2 parts */
+ if( p_pes->i_nb_data >= 2 && p_stream->i_cat == AUDIO_ES )
+ {
+ pes_packet_t *p_pes_;
+ data_packet_t *p_data;
+ int i_nb_data;
+
+ p_pes_ = PES_split( p_input, p_stream, p_pes );
+ if( p_pes_->i_nb_data >= 2 )
+ {
+ input_DecodePES( p_stream->p_es->p_decoder_fifo, PES_split( p_input,p_stream,p_pes_ ) );
+ }
+ input_DecodePES( p_stream->p_es->p_decoder_fifo,p_pes_ );
+ if( p_pes->i_nb_data >= 2 )
+ {
+ input_DecodePES( p_stream->p_es->p_decoder_fifo, PES_split( p_input,p_stream,p_pes ) );
+ }
+ //input_DecodePES( p_stream->p_es->p_decoder_fifo,p_pes );
+ }
+#endif
input_DecodePES( p_stream->p_es->p_decoder_fifo, p_pes );
}
else
* libavi.c :
*****************************************************************************
* Copyright (C) 2001 VideoLAN
- * $Id: libavi.c,v 1.12 2002/12/18 16:16:30 sam Exp $
+ * $Id: libavi.c,v 1.13 2003/01/11 18:10:49 fenrir Exp $
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
*
* This program is free software; you can redistribute it and/or modify
if( p_chk->strf.auds.p_wf->cbSize > 0 )
{
memcpy( &p_chk->strf.auds.p_wf[1] ,
- p_buff + sizeof( WAVEFORMATEX ),
+ p_buff + 8 + sizeof( WAVEFORMATEX ), // 8=fourrc+size
p_chk->strf.auds.p_wf->cbSize );
}
#ifdef AVI_DEBUG
if( p_chk->strf.vids.p_bih->biSize - sizeof(BITMAPINFOHEADER) > 0 )
{
memcpy( &p_chk->strf.vids.p_bih[1],
- p_buff + sizeof(BITMAPINFOHEADER),
+ p_buff + 8 + sizeof(BITMAPINFOHEADER), // 8=fourrc+size
p_chk->strf.vids.p_bih->biSize -
sizeof(BITMAPINFOHEADER) );
}
AVI_READCHUNK_ENTER;
p_chk->strd.p_data = malloc( p_chk->common.i_chunk_size );
memcpy( p_chk->strd.p_data,
- p_buff,
+ p_buff + 8,
p_chk->common.i_chunk_size );
AVI_READCHUNK_EXIT( VLC_SUCCESS );
}