Commit 5c196547 authored by Laurent Aimar's avatar Laurent Aimar

* faad: can read stream with multiple frames per pes_packet_t (for mkv).

parent 57b971e9
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* decoder.c: AAC decoder using libfaad2 * decoder.c: AAC decoder using libfaad2
***************************************************************************** *****************************************************************************
* Copyright (C) 2001, 2002 VideoLAN * Copyright (C) 2001, 2002 VideoLAN
* $Id: decoder.c,v 1.24 2003/06/14 22:14:16 hartman Exp $ * $Id: decoder.c,v 1.25 2003/06/22 08:49:11 fenrir Exp $
* *
* Authors: Laurent Aimar <fenrir@via.ecp.fr> * Authors: Laurent Aimar <fenrir@via.ecp.fr>
* *
...@@ -120,14 +120,17 @@ static int RunDecoder( decoder_fifo_t *p_fifo ) ...@@ -120,14 +120,17 @@ static int RunDecoder( decoder_fifo_t *p_fifo )
return( 0 ); return( 0 );
} }
static unsigned int pi_channels_maps[6] = static unsigned int pi_channels_maps[7] =
{ {
0, 0,
AOUT_CHAN_CENTER, AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT, AOUT_CHAN_CENTER,
AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
AOUT_CHAN_CENTER | AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT, AOUT_CHAN_CENTER | AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT, AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT,
AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT,
| AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT /* FIXME */
AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT | AOUT_CHAN_REARCENTER,
}; };
#define FREE( p ) if( p != NULL ) free( p ); p = NULL #define FREE( p ) if( p != NULL ) free( p ); p = NULL
...@@ -316,6 +319,7 @@ static void DecodeThread( adec_thread_t *p_adec ) ...@@ -316,6 +319,7 @@ static void DecodeThread( adec_thread_t *p_adec )
faacDecFrameInfo faad_frame; faacDecFrameInfo faad_frame;
int i_frame_size; int i_frame_size;
pes_packet_t *p_pes; pes_packet_t *p_pes;
int i_used;
/* **** Get a new frames from streams **** */ /* **** Get a new frames from streams **** */
do do
...@@ -346,104 +350,110 @@ static void DecodeThread( adec_thread_t *p_adec ) ...@@ -346,104 +350,110 @@ static void DecodeThread( adec_thread_t *p_adec )
input_DeletePES( p_adec->p_fifo->p_packets_mgt, p_pes ); input_DeletePES( p_adec->p_fifo->p_packets_mgt, p_pes );
} while( i_frame_size <= 0 ); } while( i_frame_size <= 0 );
/* **** decode this frame **** */
i_used = 0;
while( i_used < i_frame_size )
{
/* **** decode this frame **** */
#ifdef HAVE_OLD_FAAD2 #ifdef HAVE_OLD_FAAD2
p_faad_buffer = faacDecDecode( p_adec->p_handle, p_faad_buffer = faacDecDecode( p_adec->p_handle,
&faad_frame, &faad_frame,
p_adec->p_buffer ); &p_adec->p_buffer[i_used] );
#else #else
p_faad_buffer = faacDecDecode( p_adec->p_handle, p_faad_buffer = faacDecDecode( p_adec->p_handle,
&faad_frame, &faad_frame,
p_adec->p_buffer, &p_adec->p_buffer[i_used],
i_frame_size ); i_frame_size - i_used );
#endif #endif
/* **** some sanity checks to see if we have samples to out **** */ /* **** some sanity checks to see if we have samples to out **** */
if( faad_frame.error > 0 ) if( faad_frame.error > 0 )
{ {
msg_Warn( p_adec->p_fifo, "%s", msg_Warn( p_adec->p_fifo, "%s",
faacDecGetErrorMessage(faad_frame.error) ); faacDecGetErrorMessage(faad_frame.error) );
return; return;
} }
if( ( faad_frame.channels <= 0 )|| if( ( faad_frame.channels <= 0 )||
( faad_frame.channels > AAC_MAXCHANNELS) || ( faad_frame.channels > AAC_MAXCHANNELS) ||
( faad_frame.channels > 5 ) ) ( faad_frame.channels > 6 ) )
{ {
msg_Warn( p_adec->p_fifo, msg_Warn( p_adec->p_fifo,
"invalid channels count(%d)", faad_frame.channels ); "invalid channels count(%d)", faad_frame.channels );
return; return;
} }
if( faad_frame.samples <= 0 ) if( faad_frame.samples <= 0 )
{ {
msg_Warn( p_adec->p_fifo, "decoded zero sample !" ); msg_Warn( p_adec->p_fifo, "decoded zero sample !" );
return; return;
} }
#if 0 #if 0
msg_Dbg( p_adec->p_fifo, msg_Dbg( p_adec->p_fifo,
"decoded frame samples:%d, channels:%d, consumed:%d", "decoded frame samples:%d, channels:%d, consumed:%d",
faad_frame.samples, faad_frame.samples,
faad_frame.channels, faad_frame.channels,
faad_frame.bytesconsumed ); faad_frame.bytesconsumed );
#endif #endif
i_used += faad_frame.bytesconsumed;
/* **** Now we can output these samples **** */ /* **** Now we can output these samples **** */
/* **** First check if we have a valid output **** */ /* **** First check if we have a valid output **** */
if( ( !p_adec->p_aout_input )|| if( ( !p_adec->p_aout_input )||
( p_adec->output_format.i_original_channels != ( p_adec->output_format.i_original_channels !=
pi_channels_maps[faad_frame.channels] ) ) pi_channels_maps[faad_frame.channels] ) )
{
if( p_adec->p_aout_input )
{ {
/* **** Delete the old **** */ if( p_adec->p_aout_input )
aout_DecDelete( p_adec->p_aout, p_adec->p_aout_input ); {
} /* **** Delete the old **** */
aout_DecDelete( p_adec->p_aout, p_adec->p_aout_input );
}
/* **** Create a new audio output **** */ /* **** Create a new audio output **** */
p_adec->output_format.i_physical_channels = p_adec->output_format.i_physical_channels =
p_adec->output_format.i_original_channels = p_adec->output_format.i_original_channels =
pi_channels_maps[faad_frame.channels]; pi_channels_maps[faad_frame.channels];
aout_DateInit( &p_adec->date, p_adec->output_format.i_rate ); aout_DateInit( &p_adec->date, p_adec->output_format.i_rate );
p_adec->p_aout_input = aout_DecNew( p_adec->p_fifo, p_adec->p_aout_input = aout_DecNew( p_adec->p_fifo,
&p_adec->p_aout, &p_adec->p_aout,
&p_adec->output_format ); &p_adec->output_format );
} }
if( !p_adec->p_aout_input ) if( !p_adec->p_aout_input )
{ {
msg_Err( p_adec->p_fifo, "cannot create aout" ); msg_Err( p_adec->p_fifo, "cannot create aout" );
return; return;
} }
if( p_adec->pts != 0 && p_adec->pts != aout_DateGet( &p_adec->date ) ) if( p_adec->pts != 0 && p_adec->pts != aout_DateGet( &p_adec->date ) )
{ {
aout_DateSet( &p_adec->date, p_adec->pts ); aout_DateSet( &p_adec->date, p_adec->pts );
} }
else if( !aout_DateGet( &p_adec->date ) ) else if( !aout_DateGet( &p_adec->date ) )
{ {
return; return;
} }
p_aout_buffer = aout_DecNewBuffer( p_adec->p_aout, p_aout_buffer = aout_DecNewBuffer( p_adec->p_aout,
p_adec->p_aout_input, p_adec->p_aout_input,
faad_frame.samples / faad_frame.channels ); faad_frame.samples / faad_frame.channels );
if( !p_aout_buffer ) if( !p_aout_buffer )
{ {
msg_Err( p_adec->p_fifo, "cannot get aout buffer" ); msg_Err( p_adec->p_fifo, "cannot get aout buffer" );
p_adec->p_fifo->b_error = 1; p_adec->p_fifo->b_error = 1;
return; return;
}
p_aout_buffer->start_date = aout_DateGet( &p_adec->date );
p_aout_buffer->end_date = aout_DateIncrement( &p_adec->date,
faad_frame.samples /
faad_frame.channels );
memcpy( p_aout_buffer->p_buffer,
p_faad_buffer,
p_aout_buffer->i_nb_bytes );
aout_DecPlay( p_adec->p_aout, p_adec->p_aout_input, p_aout_buffer );
} }
p_aout_buffer->start_date = aout_DateGet( &p_adec->date );
p_aout_buffer->end_date = aout_DateIncrement( &p_adec->date,
faad_frame.samples /
faad_frame.channels );
memcpy( p_aout_buffer->p_buffer,
p_faad_buffer,
p_aout_buffer->i_nb_bytes );
aout_DecPlay( p_adec->p_aout, p_adec->p_aout_input, p_aout_buffer );
} }
......
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