* araw.c: Pseudo audio decoder; for raw pcm data
*****************************************************************************
* Copyright (C) 2001, 2002 VideoLAN
- * $Id: araw.c,v 1.2 2002/10/20 17:44:17 fenrir Exp $
+ * $Id: araw.c,v 1.11 2003/01/07 21:49:01 fenrir Exp $
*
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
*
#include <stdlib.h> /* malloc(), free() */
#include <string.h> /* strdup() */
-
+#include "codecs.h"
/*****************************************************************************
* Local prototypes
*****************************************************************************/
-typedef struct waveformatex_s
-{
- u16 i_formattag;
- u16 i_channels;
- u32 i_samplespersec;
- u32 i_avgbytespersec;
- u16 i_blockalign;
- u16 i_bitspersample;
- u16 i_size; /* the extra size in bytes */
- u8 *p_data; /* The extra data */
-} waveformatex_t;
typedef struct adec_thread_s
{
- waveformatex_t format;
+ WAVEFORMATEX *p_wf;
+
+ //waveformatex_t format;
/* The bit stream structure handles the PES stream at the bit level */
- bit_stream_t bit_stream;
+// bit_stream_t bit_stream;
/* Input properties */
decoder_fifo_t *p_fifo;
vlc_module_end();
-static int i_channels_maps[6] =
+static int pi_channels_maps[6] =
{
0,
- AOUT_CHAN_MONO, AOUT_CHAN_STEREO,
- AOUT_CHAN_3F, AOUT_CHAN_2F2R,
- AOUT_CHAN_3F2R
+ AOUT_CHAN_CENTER,
+ AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
+ AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER,
+ AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARLEFT,
+ AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
+ | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARLEFT
};
/*****************************************************************************
#define GetDWLE( p ) \
( *(u8*)(p) + ( *((u8*)(p)+1) << 8 ) + \
( *((u8*)(p)+2) << 16 ) + ( *((u8*)(p)+3) << 24 ) )
-
+
+#if 0
static void GetWaveFormatEx( waveformatex_t *p_wh,
u8 *p_data )
{
}
}
}
-
-/* get the first pes from fifo */
-static pes_packet_t *PESGetFirst( decoder_fifo_t *p_fifo )
-{
- pes_packet_t *p_pes;
-
- vlc_mutex_lock( &p_fifo->data_lock );
-
- /* if fifo is empty wait */
- while( !p_fifo->p_first )
- {
- if( p_fifo->b_die )
- {
- vlc_mutex_unlock( &p_fifo->data_lock );
- return NULL;
- }
- vlc_cond_wait( &p_fifo->data_wait, &p_fifo->data_lock );
- }
- p_pes = p_fifo->p_first;
-
- vlc_mutex_unlock( &p_fifo->data_lock );
-
- return p_pes;
-}
-static int PESGetSize( pes_packet_t *p_pes )
-{
- data_packet_t *p_data;
- int i_size = 0;
-
- if( !p_pes )
- {
- return( 0 );
- }
-
- for( p_data = p_pes->p_first; p_data != NULL; p_data = p_data->p_next )
- {
- i_size += p_data->p_payload_end - p_data->p_payload_start;
- }
-
- return( i_size );
-}
-
+#endif
/*****************************************************************************
* InitThread: initialize data before entering main loop
static int InitThread( adec_thread_t * p_adec )
{
-
- if( p_adec->p_fifo->p_demux_data )
- {
- GetWaveFormatEx( &p_adec->format,
- (u8*)p_adec->p_fifo->p_demux_data );
- /* fixing some values */
- if( p_adec->format.i_formattag == 1 && !p_adec->format.i_blockalign )
- {
- p_adec->format.i_blockalign = p_adec->format.i_channels *
- ( ( p_adec->format.i_bitspersample + 7 ) / 8 );
- }
- }
- else
+ if( ( p_adec->p_wf = (WAVEFORMATEX*)p_adec->p_fifo->p_waveformatex ) == NULL )
{
msg_Err( p_adec->p_fifo, "unknown raw format" );
return( -1 );
}
+ /* fixing some values */
+ if( p_adec->p_wf->wFormatTag == WAVE_FORMAT_PCM &&
+ !p_adec->p_wf->nBlockAlign )
+ {
+ p_adec->p_wf->nBlockAlign =
+ p_adec->p_wf->nChannels *
+ ( ( p_adec->p_wf->wBitsPerSample + 7 ) / 8 );
+ }
+
msg_Dbg( p_adec->p_fifo,
"raw format: samplerate:%dHz channels:%d bits/sample:%d blockalign:%d",
- p_adec->format.i_samplespersec,
- p_adec->format.i_channels,
- p_adec->format.i_bitspersample, p_adec->format.i_blockalign );
+ p_adec->p_wf->nSamplesPerSec,
+ p_adec->p_wf->nChannels,
+ p_adec->p_wf->wBitsPerSample,
+ p_adec->p_wf->nBlockAlign );
/* Initialize the thread properties */
- switch( ( p_adec->format.i_bitspersample + 7 ) / 8 )
+ switch( ( p_adec->p_wf->wBitsPerSample + 7 ) / 8 )
{
case( 2 ):
p_adec->output_format.i_format = VLC_FOURCC('s','1','6','l');
case( 4 ):
p_adec->output_format.i_format = VLC_FOURCC('s','3','2','l');
break;
-
case( 1 ):
+ p_adec->output_format.i_format = VLC_FOURCC('u','8',' ',' ');
+ break;
default:
msg_Err( p_adec->p_fifo, "bad parameters(bits/sample)" );
return( -1 );
}
- p_adec->output_format.i_rate = p_adec->format.i_samplespersec;
- if( p_adec->output_format.i_channels <= 0 ||
- p_adec->output_format.i_channels > 5 )
+ p_adec->output_format.i_rate = p_adec->p_wf->nSamplesPerSec;
+
+ if( p_adec->p_wf->nChannels <= 0 ||
+ p_adec->p_wf->nChannels > 5 )
{
msg_Err( p_adec->p_fifo, "bad channels count(1-5)" );
return( -1 );
}
- p_adec->output_format.i_channels =
- i_channels_maps[p_adec->format.i_channels];
+ p_adec->output_format.i_physical_channels =
+ p_adec->output_format.i_original_channels =
+ pi_channels_maps[p_adec->p_wf->nChannels];
p_adec->p_aout = NULL;
p_adec->p_aout_input = NULL;
}
/* Init the BitStream */
- InitBitstream( &p_adec->bit_stream, p_adec->p_fifo,
- NULL, NULL );
+// InitBitstream( &p_adec->bit_stream, p_adec->p_fifo,
+// NULL, NULL );
return( 0 );
}
+static void GetPESData( u8 *p_buf, int i_max, pes_packet_t *p_pes )
+{
+ int i_copy;
+ int i_count;
+
+ data_packet_t *p_data;
+
+ i_count = 0;
+ p_data = p_pes->p_first;
+ while( p_data != NULL && i_count < i_max )
+ {
+
+ i_copy = __MIN( p_data->p_payload_end - p_data->p_payload_start, i_max - i_count );
+
+ if( i_copy > 0 )
+ {
+ memcpy( p_buf,
+ p_data->p_payload_start,
+ i_copy );
+ }
+
+ p_data = p_data->p_next;
+ i_count += i_copy;
+ p_buf += i_copy;
+ }
+
+ if( i_count < i_max )
+ {
+ memset( p_buf, 0, i_max - i_count );
+ }
+}
+
/*****************************************************************************
* DecodeThread: decodes a frame
*****************************************************************************/
aout_buffer_t *p_aout_buffer;
int i_samples; // per channels
int i_size;
+
pes_packet_t *p_pes;
/* **** get samples count **** */
- p_pes = PESGetFirst( p_adec->p_fifo );
-
- i_size = PESGetSize( p_pes );
- if( p_adec->format.i_blockalign > 0 )
+ input_ExtractPES( p_adec->p_fifo, &p_pes );
+ if( !p_pes )
+ {
+ p_adec->p_fifo->b_error = 1;
+ return;
+ }
+ i_size = p_pes->i_pes_size;
+
+ if( p_adec->p_wf->nBlockAlign > 0 )
{
- i_size -= i_size % p_adec->format.i_blockalign;
+ i_size -= i_size % p_adec->p_wf->nBlockAlign;
}
- i_size = __MAX( i_size, p_adec->format.i_blockalign );
+ i_size = __MAX( i_size, p_adec->p_wf->nBlockAlign );
if( !i_size || !p_pes )
{
return;
}
i_samples = i_size /
- ( ( p_adec->format.i_bitspersample + 7 ) / 8 ) /
- p_adec->format.i_channels;
+ ( ( p_adec->p_wf->wBitsPerSample + 7 ) / 8 ) /
+ p_adec->p_wf->nChannels;
// msg_Warn( p_adec->p_fifo, "got %d samples (%d bytes)", i_samples, i_size );
p_adec->pts = p_pes->i_pts;
p_aout_buffer->start_date = aout_DateGet( &p_adec->date );
p_aout_buffer->end_date = aout_DateIncrement( &p_adec->date,
i_samples );
- GetChunk( &p_adec->bit_stream,
- p_aout_buffer->p_buffer,
- p_aout_buffer->i_nb_bytes );
+
+ GetPESData( p_aout_buffer->p_buffer, p_aout_buffer->i_nb_bytes, p_pes );
aout_DecPlay( p_adec->p_aout, p_adec->p_aout_input, p_aout_buffer );
+
+
+ input_DeletePES( p_adec->p_fifo->p_packets_mgt, p_pes );
}
aout_DecDelete( p_adec->p_aout, p_adec->p_aout_input );
}
- FREE( p_adec->format.p_data );
-
msg_Dbg( p_adec->p_fifo, "raw audio decoder closed" );
free( p_adec );