-/******************************************************************************
- * audio_decoder.c: MPEG1 Layer I-II audio decoder thread
- * (c)1999 VideoLAN
- ******************************************************************************/
+/*****************************************************************************
+ * audio_decoder.c: MPEG audio decoder thread
+ *****************************************************************************
+ * Copyright (C) 1999, 2000 VideoLAN
+ * $Id: audio_decoder.c,v 1.50 2001/05/01 04:18:18 sam Exp $
+ *
+ * Authors: Michel Kaempf <maxx@via.ecp.fr>
+ * Michel Lespinasse <walken@via.ecp.fr>
+ * Samuel Hocevar <sam@via.ecp.fr>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
+ *****************************************************************************/
/*
* TODO :
- * - Optimiser les NeedBits() et les GetBits() du code là où c'est possible
+ *
+ * - optimiser les NeedBits() et les GetBits() du code là où c'est possible ;
+ * - vlc_cond_signal() / vlc_cond_wait() ;
+ *
*/
-/******************************************************************************
+/*****************************************************************************
* Preamble
- ******************************************************************************/
-#include <unistd.h>
+ *****************************************************************************/
+#include "defs.h"
-#include <pthread.h>
-#include <stdio.h> /* "intf_msg.h" */
-#include <stdlib.h> /* malloc(), free() */
-#include <netinet/in.h> /* ntohl() */
-#include <sys/soundcard.h> /* "audio_output.h" */
-#include <sys/uio.h> /* "input.h" */
+#include <unistd.h> /* getpid() */
+
+#include <stdio.h> /* "intf_msg.h" */
+#include <string.h> /* memcpy(), memset() */
+#include <stdlib.h> /* malloc(), free() */
-#include "common.h"
#include "config.h"
+#include "common.h"
+#include "threads.h"
#include "mtime.h"
-#include "debug.h" /* "input_netlist.h" */
-#include "intf_msg.h" /* intf_DbgMsg(), intf_ErrMsg() */
+#include "intf_msg.h" /* intf_DbgMsg(), intf_ErrMsg() */
+
+#include "stream_control.h"
+#include "input_ext-dec.h"
-#include "input.h" /* pes_packet_t */
-#include "input_netlist.h" /* input_NetlistFreePES() */
-#include "decoder_fifo.h" /* DECODER_FIFO_(ISEMPTY|START|INCSTART)() */
+#include "audio_output.h" /* aout_fifo_t (for audio_decoder.h) */
-#include "audio_output.h"
-
-#include "audio_constants.h"
+#include "adec_generic.h"
#include "audio_decoder.h"
-#include "audio_math.h"
-
-/******************************************************************************
- * Local prototypes
- ******************************************************************************/
-static int InitThread ( adec_thread_t * p_adec );
-static void RunThread ( adec_thread_t * p_adec );
-static void ErrorThread ( adec_thread_t * p_adec );
-static void EndThread ( adec_thread_t * p_adec );
+#include "adec_math.h" /* DCT32(), PCM() */
-static int adec_Layer1_Mono ( adec_thread_t * p_adec );
-static int adec_Layer1_Stereo ( adec_thread_t * p_adec );
-static int adec_Layer2_Mono ( adec_thread_t * p_adec );
-static int adec_Layer2_Stereo ( adec_thread_t * p_adec );
+#define ADEC_FRAME_SIZE (2*1152)
-static byte_t GetByte ( bit_stream_t * p_bit_stream );
-static void NeedBits ( bit_stream_t * p_bit_stream, int i_bits );
-static void DumpBits ( bit_stream_t * p_bit_stream, int i_bits );
-static int FindHeader ( adec_thread_t * p_adec );
+/*****************************************************************************
+ * Local prototypes
+ *****************************************************************************/
+static int InitThread (adec_thread_t * p_adec);
+static void RunThread (adec_thread_t * p_adec);
+static void ErrorThread (adec_thread_t * p_adec);
+static void EndThread (adec_thread_t * p_adec);
-/******************************************************************************
+/*****************************************************************************
* adec_CreateThread: creates an audio decoder thread
- ******************************************************************************
+ *****************************************************************************
* This function creates a new audio decoder thread, and returns a pointer to
* its description. On error, it returns NULL.
- ******************************************************************************/
-adec_thread_t * adec_CreateThread( input_thread_t * p_input )
+ *****************************************************************************/
+vlc_thread_t adec_CreateThread ( adec_config_t * p_config )
{
adec_thread_t * p_adec;
- intf_DbgMsg("adec debug: creating audio decoder thread\n");
+ intf_DbgMsg ( "adec debug: creating audio decoder thread" );
/* Allocate the memory needed to store the thread's structure */
- if ( (p_adec = (adec_thread_t *)malloc( sizeof(adec_thread_t) )) == NULL )
+ if ( (p_adec = (adec_thread_t *)malloc (sizeof(adec_thread_t))) == NULL )
{
- intf_ErrMsg("adec error: not enough memory for adec_CreateThread() to create the new thread\n");
- return( NULL );
+ intf_ErrMsg ( "adec error: not enough memory for"
+ " adec_CreateThread() to create the new thread" );
+ return 0;
}
/*
* Initialize the thread properties
*/
- p_adec->b_die = 0;
- p_adec->b_error = 0;
-
- /*
- * Initialize the input properties
- */
- /* Initialize the decoder fifo's data lock and conditional variable and set
- * its buffer as empty */
- pthread_mutex_init( &p_adec->fifo.data_lock, NULL );
- pthread_cond_init( &p_adec->fifo.data_wait, NULL );
- p_adec->fifo.i_start = 0;
- p_adec->fifo.i_end = 0;
- /* Initialize the bit stream structure */
- p_adec->bit_stream.p_input = p_input;
- p_adec->bit_stream.p_decoder_fifo = &p_adec->fifo;
- p_adec->bit_stream.fifo.buffer = 0;
- p_adec->bit_stream.fifo.i_available = 0;
+ p_adec->p_config = p_config;
+ p_adec->p_fifo = p_config->decoder_config.p_decoder_fifo;
/*
* Initialize the decoder properties
*/
- p_adec->bank_0.actual = p_adec->bank_0.v1;
- p_adec->bank_0.pos = 0;
- p_adec->bank_1.actual = p_adec->bank_1.v1;
- p_adec->bank_1.pos = 0;
+ adec_Init ( p_adec );
/*
* Initialize the output properties
*/
- p_adec->p_aout = p_input->p_aout;
p_adec->p_aout_fifo = NULL;
/* Spawn the audio decoder thread */
- if ( pthread_create(&p_adec->thread_id, NULL, (void *)RunThread, (void *)p_adec) )
- {
- intf_ErrMsg("adec error: can't spawn audio decoder thread\n");
- free( p_adec );
- return( NULL );
- }
-
- intf_DbgMsg("adec debug: audio decoder thread (%p) created\n", p_adec);
- return( p_adec );
-}
-
-/******************************************************************************
- * adec_DestroyThread: destroys an audio decoder thread
- ******************************************************************************
- * This function asks an audio decoder thread to terminate. This function has
- * not to wait until the decoder thread has really died, because the killer (ie
- * this function's caller) is the input thread, that's why we are sure that no
- * other thread will try to access to this thread's descriptor after its
- * destruction.
- ******************************************************************************/
-void adec_DestroyThread( adec_thread_t * p_adec )
-{
- intf_DbgMsg("adec debug: requesting termination of audio decoder thread %p\n", p_adec);
-
- /* Ask thread to kill itself */
- p_adec->b_die = 1;
-
- /* Remove this as soon as the "status" flag is implemented */
- pthread_join( p_adec->thread_id, NULL ); /* wait until it's done */
-}
-
-/* Following functions are local */
-
-/******************************************************************************
- * GetByte : reads the next byte in the input stream
- ******************************************************************************/
-static __inline__ byte_t GetByte( bit_stream_t * p_bit_stream )
-{
- /* Are there some bytes left in the current TS packet ? */
- if ( p_bit_stream->i_byte < p_bit_stream->p_ts->i_payload_end )
- {
- return( p_bit_stream->p_ts->buffer[ p_bit_stream->i_byte++ ] );
- }
- else
- {
- /* We are looking for the next TS packet that contains real data,
- * and not just a PES header */
- do
- {
- /* We were reading the last TS packet of this PES packet... It's
- * time to jump to the next PES packet */
- if ( p_bit_stream->p_ts->p_next_ts == NULL )
- {
- /* We are going to read/write the start and end indexes of the
- * decoder fifo and to use the fifo's conditional variable,
- * that's why we need to take the lock before */
- pthread_mutex_lock( &p_bit_stream->p_decoder_fifo->data_lock );
-
- /* We should increase the start index of the decoder fifo, but
- * if we do this now, the input thread could overwrite the
- * pointer to the current PES packet, and we weren't able to
- * give it back to the netlist. That's why we free the PES
- * packet first. */
- input_NetlistFreePES( p_bit_stream->p_input, DECODER_FIFO_START(*p_bit_stream->p_decoder_fifo) );
- DECODER_FIFO_INCSTART( *p_bit_stream->p_decoder_fifo );
-
- /* !! b_die !! */
- while ( DECODER_FIFO_ISEMPTY(*p_bit_stream->p_decoder_fifo) )
- {
- pthread_cond_wait( &p_bit_stream->p_decoder_fifo->data_wait,
- &p_bit_stream->p_decoder_fifo->data_lock );
- }
-
- /* The next byte could be found in the next PES packet */
-#ifdef DEBUG
-// fprintf(stderr, "*");
-#endif
- p_bit_stream->p_ts = DECODER_FIFO_START( *p_bit_stream->p_decoder_fifo )->p_first_ts;
-
- /* We can release the fifo's data lock */
- pthread_mutex_unlock( &p_bit_stream->p_decoder_fifo->data_lock );
- }
- /* Perhaps the next TS packet of the current PES packet contains
- * real data (ie its payload's size is greater than 0) */
- else
- {
-#ifdef DEBUG
-// fprintf(stderr, ".");
-#endif
- p_bit_stream->p_ts = p_bit_stream->p_ts->p_next_ts;
- }
- } while ( p_bit_stream->p_ts->i_payload_start == p_bit_stream->p_ts->i_payload_end );
-
- /* We've found a TS packet which contains interesting data... As we
- * return the payload's first byte, we set i_byte to the following
- * one */
- p_bit_stream->i_byte = p_bit_stream->p_ts->i_payload_start;
- return( p_bit_stream->p_ts->buffer[ p_bit_stream->i_byte++ ] );
- }
-}
-
-/******************************************************************************
- * NeedBits : reads i_bits new bits in the bit stream and stores them in the
- * bit buffer
- ******************************************************************************
- * - i_bits must be less or equal 32 !
- * - There is something important to notice with that function : if the number
- * of bits available in the bit buffer when calling NeedBits() is greater than
- * 24 (i_available > 24) but less than the number of needed bits
- * (i_available < i_bits), the byte returned by GetByte() will be shifted with
- * a negative value and the number of bits available in the bit buffer will be
- * set to more than 32 !
- ******************************************************************************/
-static __inline__ void NeedBits( bit_stream_t * p_bit_stream, int i_bits )
-{
- while ( p_bit_stream->fifo.i_available < i_bits )
- {
- p_bit_stream->fifo.buffer |= ((u32)GetByte( p_bit_stream )) << (24 - p_bit_stream->fifo.i_available);
- p_bit_stream->fifo.i_available += 8;
- }
-}
-
-/******************************************************************************
- * DumpBits : removes i_bits bits from the bit buffer
- ******************************************************************************
- * - i_bits <= i_available
- * - i_bits < 32 (because (u32 << 32) <=> (u32 = u32))
- ******************************************************************************/
-static __inline__ void DumpBits( bit_stream_t * p_bit_stream, int i_bits )
-{
- p_bit_stream->fifo.buffer <<= i_bits;
- p_bit_stream->fifo.i_available -= i_bits;
-}
-
-/******************************************************************************
- * FindHeader : parses an input stream until an audio frame header could be
- * found
- ******************************************************************************
- * When this function returns successfully, the header can be found in the
- * buffer of the bit stream fifo.
- ******************************************************************************/
-static int FindHeader( adec_thread_t * p_adec )
-{
- while ( (!p_adec->b_die) && (!p_adec->b_error) )
+ if ( vlc_thread_create(&p_adec->thread_id, "audio decoder",
+ (vlc_thread_func_t)RunThread, (void *)p_adec) )
{
- NeedBits( &p_adec->bit_stream, 32 );
- if ( (p_adec->bit_stream.fifo.buffer & ADEC_HEADER_SYNCWORD_MASK) == ADEC_HEADER_SYNCWORD_MASK )
- {
-#ifdef DEBUG
-// fprintf(stderr, "H");
-#endif
- return( 0 );
- }
-#ifdef DEBUG
-// fprintf(stderr, "!");
-#endif
- DumpBits( &p_adec->bit_stream, 8 );
+ intf_ErrMsg ("adec error: can't spawn audio decoder thread");
+ free (p_adec);
+ return 0;
}
- return( -1 );
+ intf_DbgMsg ("adec debug: audio decoder thread (%p) created", p_adec);
+ return p_adec->thread_id;
}
-/******************************************************************************
- * adec_Layer`L'_`M': decodes an mpeg 1, layer `L', mode `M', audio frame
- ******************************************************************************
- * These functions decode the audio frame which has already its header loaded
- * in the i_header member of the audio decoder thread structure and its first
- * byte of data described by the bit stream structure of the audio decoder
- * thread (there is no bit available in the bit buffer yet)
- ******************************************************************************/
-
-/******************************************************************************
- * adec_Layer1_Mono
- ******************************************************************************/
-static __inline__ int adec_Layer1_Mono( adec_thread_t * p_adec )
-{
- p_adec->bit_stream.fifo.buffer = 0;
- p_adec->bit_stream.fifo.i_available = 0;
- return( 0 );
-}
-
-/******************************************************************************
- * adec_Layer1_Stereo
- ******************************************************************************/
-static __inline__ int adec_Layer1_Stereo( adec_thread_t * p_adec )
-{
- p_adec->bit_stream.fifo.buffer = 0;
- p_adec->bit_stream.fifo.i_available = 0;
- return( 0 );
-}
-
-/******************************************************************************
- * adec_Layer2_Mono
- ******************************************************************************/
-static __inline__ int adec_Layer2_Mono( adec_thread_t * p_adec )
-{
- p_adec->bit_stream.fifo.buffer = 0;
- p_adec->bit_stream.fifo.i_available = 0;
- return( 0 );
-}
-
-/******************************************************************************
- * adec_Layer2_Stereo
- ******************************************************************************/
-static __inline__ int adec_Layer2_Stereo( adec_thread_t * p_adec )
-{
- typedef struct requantization_s
- {
- byte_t i_bits_per_codeword;
- const float * pf_ungroup;
- float f_slope;
- float f_offset;
- } requantization_t;
+/* following functions are local */
- static const float pf_scalefactor[64] = ADEC_SCALE_FACTOR;
-
- static u32 i_header;
- static int i_sampling_frequency, i_mode, i_bound;
- static int pi_allocation_0[32], pi_allocation_1[32]; /* see ISO/IEC 11172-3 2.4.1.6 */
- int i_sb, i_nbal;
- float f_scalefactor_0, f_scalefactor_1;
-
- static const byte_t ppi_bitrate_per_channel_index[4][15] = ADEC_LAYER2_BITRATE_PER_CHANNEL_INDEX;
- static const byte_t ppi_sblimit[3][11] = ADEC_LAYER2_SBLIMIT;
- static const byte_t ppi_nbal[2][32] = ADEC_LAYER2_NBAL;
-
- static const float pf_ungroup3[3*3*3 * 3] = ADEC_LAYER2_UNGROUP3;
- static const float pf_ungroup5[5*5*5 * 3] = ADEC_LAYER2_UNGROUP5;
- static const float pf_ungroup9[9*9*9 * 3] = ADEC_LAYER2_UNGROUP9;
-
- static const requantization_t p_requantization_cd[16] = ADEC_LAYER2_REQUANTIZATION_CD;
- static const requantization_t p_requantization_ab1[16] = ADEC_LAYER2_REQUANTIZATION_AB1;
- static const requantization_t p_requantization_ab2[16] = ADEC_LAYER2_REQUANTIZATION_AB2;
- static const requantization_t p_requantization_ab3[16] = ADEC_LAYER2_REQUANTIZATION_AB3;
- static const requantization_t p_requantization_ab4[16] = ADEC_LAYER2_REQUANTIZATION_AB4;
- static const requantization_t * pp_requantization_ab[30] = ADEC_LAYER2_REQUANTIZATION_AB;
-
- static int i_sblimit, i_bitrate_per_channel_index;
- static int pi_scfsi_0[30], pi_scfsi_1[30];
- static const byte_t * pi_nbal;
- static float ppf_sample_0[3][32], ppf_sample_1[3][32];
- static const requantization_t * pp_requantization_0[30];
- static const requantization_t * pp_requantization_1[30];
- static requantization_t requantization;
- static const float * pf_ungroup;
-
- static float pf_scalefactor_0_0[30], pf_scalefactor_0_1[30], pf_scalefactor_0_2[30];
- static float pf_scalefactor_1_0[30], pf_scalefactor_1_1[30], pf_scalefactor_1_2[30];
-
- int i_2nbal, i_gr;
- float f_dummy;
-
- long l_end_frame;
- s16 * p_s16;
-
- int i_need = 0, i_dump = 0;
-// static const int pi_framesize[512] = ADEC_FRAME_SIZE;
-
- /* Read the audio frame header and flush the bit buffer */
- i_header = p_adec->bit_stream.fifo.buffer;
- p_adec->bit_stream.fifo.buffer = 0;
- p_adec->bit_stream.fifo.i_available = 0;
- /* Read the sampling frequency (see ISO/IEC 11172-3 2.4.2.3) */
- i_sampling_frequency = (int)((i_header & ADEC_HEADER_SAMPLING_FREQUENCY_MASK)
- >> ADEC_HEADER_SAMPLING_FREQUENCY_SHIFT);
- /* Read the mode (see ISO/IEC 11172-3 2.4.2.3) */
- i_mode = (int)((i_header & ADEC_HEADER_MODE_MASK) >> ADEC_HEADER_MODE_SHIFT);
- /* If a CRC can be found in the frame, get rid of it */
- if ( (i_header & ADEC_HEADER_PROTECTION_BIT_MASK) == 0 )
- {
- GetByte( &p_adec->bit_stream );
- GetByte( &p_adec->bit_stream );
- }
-
- /* Find out the bitrate per channel index */
- i_bitrate_per_channel_index = (int)ppi_bitrate_per_channel_index[i_mode]
- [(i_header & ADEC_HEADER_BITRATE_INDEX_MASK) >> ADEC_HEADER_BITRATE_INDEX_SHIFT];
- /* Find out the number of subbands */
- i_sblimit = (int)ppi_sblimit[i_sampling_frequency][i_bitrate_per_channel_index];
- /* Check if the frame is valid or not */
- if ( i_sblimit == 0 )
- {
- return( 0 ); /* the frame is invalid */
- }
- /* Find out the number of bits allocated */
- pi_nbal = ppi_nbal[ (i_bitrate_per_channel_index <= 2) ? 0 : 1 ];
-
- /* Find out the `bound' subband (see ISO/IEC 11172-3 2.4.2.3) */
- if ( i_mode == 1 )
- {
- i_bound = (int)(((i_header & ADEC_HEADER_MODE_EXTENSION_MASK) >> (ADEC_HEADER_MODE_EXTENSION_SHIFT - 2)) + 4);
- if ( i_bound > i_sblimit )
- {
- i_bound = i_sblimit;
- }
- }
- else
- {
- i_bound = i_sblimit;
- }
-
- /* Read the allocation information (see ISO/IEC 11172-3 2.4.1.6) */
- for ( i_sb = 0; i_sb < i_bound; i_sb++ )
- {
- i_2nbal = 2 * (i_nbal = (int)pi_nbal[ i_sb ]);
- NeedBits( &p_adec->bit_stream, i_2nbal );
- i_need += i_2nbal;
- pi_allocation_0[ i_sb ] = (int)(p_adec->bit_stream.fifo.buffer >> (32 - i_nbal));
- p_adec->bit_stream.fifo.buffer <<= i_nbal;
- pi_allocation_1[ i_sb ] = (int)(p_adec->bit_stream.fifo.buffer >> (32 - i_nbal));
- p_adec->bit_stream.fifo.buffer <<= i_nbal;
- p_adec->bit_stream.fifo.i_available -= i_2nbal;
- i_dump += i_2nbal;
- }
- for ( ; i_sb < i_sblimit; i_sb++ )
- {
- i_nbal = (int)pi_nbal[ i_sb ];
- NeedBits( &p_adec->bit_stream, i_nbal );
- i_need += i_nbal;
- pi_allocation_0[ i_sb ] = (int)(p_adec->bit_stream.fifo.buffer >> (32 - i_nbal));
- DumpBits( &p_adec->bit_stream, i_nbal );
- i_dump += i_nbal;
- }
-
-#define MACRO( p_requantization ) \
- for ( i_sb = 0; i_sb < i_bound; i_sb++ ) \
- { \
- if ( pi_allocation_0[i_sb] ) \
- { \
- pp_requantization_0[i_sb] = &((p_requantization)[pi_allocation_0[i_sb]]); \
- NeedBits( &p_adec->bit_stream, 2 ); \
- i_need += 2; \
- pi_scfsi_0[i_sb] = (int)(p_adec->bit_stream.fifo.buffer >> (32 - 2)); \
- DumpBits( &p_adec->bit_stream, 2 ); \
- i_dump += 2; \
- } \
- else \
- { \
- ppf_sample_0[0][i_sb] = .0; \
- ppf_sample_0[1][i_sb] = .0; \
- ppf_sample_0[2][i_sb] = .0; \
- } \
-\
- if ( pi_allocation_1[i_sb] ) \
- { \
- pp_requantization_1[i_sb] = &((p_requantization)[pi_allocation_1[i_sb]]); \
- NeedBits( &p_adec->bit_stream, 2 ); \
- i_need += 2; \
- pi_scfsi_1[i_sb] = (int)(p_adec->bit_stream.fifo.buffer >> (32 - 2)); \
- DumpBits( &p_adec->bit_stream, 2 ); \
- i_dump += 2; \
- } \
- else \
- { \
- ppf_sample_1[0][i_sb] = .0; \
- ppf_sample_1[1][i_sb] = .0; \
- ppf_sample_1[2][i_sb] = .0; \
- } \
- } \
-\
- for ( ; i_sb < i_sblimit; i_sb++ ) \
- { \
- if ( pi_allocation_0[i_sb] ) \
- { \
- pp_requantization_0[i_sb] = &((p_requantization)[pi_allocation_0[i_sb]]); \
- NeedBits( &p_adec->bit_stream, 4 ); \
- i_need += 4; \
- pi_scfsi_0[i_sb] = (int)(p_adec->bit_stream.fifo.buffer >> (32 - 2)); \
- p_adec->bit_stream.fifo.buffer <<= 2; \
- pi_scfsi_1[i_sb] = (int)(p_adec->bit_stream.fifo.buffer >> (32 - 2)); \
- p_adec->bit_stream.fifo.buffer <<= 2; \
- p_adec->bit_stream.fifo.i_available -= 4; \
- i_dump += 4; \
- } \
- else \
- { \
- ppf_sample_0[0][i_sb] = .0; \
- ppf_sample_0[1][i_sb] = .0; \
- ppf_sample_0[2][i_sb] = .0; \
- ppf_sample_1[0][i_sb] = .0; \
- ppf_sample_1[1][i_sb] = .0; \
- ppf_sample_1[2][i_sb] = .0; \
- } \
- }
-/* #define MACRO */
-
- if ( i_bitrate_per_channel_index <= 2 )
- {
- MACRO( p_requantization_cd )
- }
- else
- {
- MACRO( pp_requantization_ab[i_sb] )
- }
-
-#define SWITCH( pi_scfsi, pf_scalefactor_0, pf_scalefactor_1, pf_scalefactor_2 ) \
- switch ( (pi_scfsi)[i_sb] ) \
- { \
- case 0: \
- NeedBits( &p_adec->bit_stream, (3*6) ); \
- i_need += 18; \
- (pf_scalefactor_0)[i_sb] = pf_scalefactor[p_adec->bit_stream.fifo.buffer >> (32 - 6)]; \
- p_adec->bit_stream.fifo.buffer <<= 6; \
- (pf_scalefactor_1)[i_sb] = pf_scalefactor[p_adec->bit_stream.fifo.buffer >> (32 - 6)]; \
- p_adec->bit_stream.fifo.buffer <<= 6; \
- (pf_scalefactor_2)[i_sb] = pf_scalefactor[p_adec->bit_stream.fifo.buffer >> (32 - 6)]; \
- p_adec->bit_stream.fifo.buffer <<= 6; \
- p_adec->bit_stream.fifo.i_available -= (3*6); \
- i_dump += 18; \
- break; \
-\
- case 1: \
- NeedBits( &p_adec->bit_stream, (2*6) ); \
- i_need += 12; \
- (pf_scalefactor_0)[i_sb] = \
- (pf_scalefactor_1)[i_sb] = pf_scalefactor[p_adec->bit_stream.fifo.buffer >> (32 - 6)]; \
- p_adec->bit_stream.fifo.buffer <<= 6; \
- (pf_scalefactor_2)[i_sb] = pf_scalefactor[p_adec->bit_stream.fifo.buffer >> (32 - 6)]; \
- p_adec->bit_stream.fifo.buffer <<= 6; \
- p_adec->bit_stream.fifo.i_available -= (2*6); \
- i_dump += 12; \
- break; \
-\
- case 2: \
- NeedBits( &p_adec->bit_stream, (1*6) ); \
- i_need += 6; \
- (pf_scalefactor_0)[i_sb] = \
- (pf_scalefactor_1)[i_sb] = \
- (pf_scalefactor_2)[i_sb] = pf_scalefactor[p_adec->bit_stream.fifo.buffer >> (32 - 6)]; \
- DumpBits( &p_adec->bit_stream, (1*6) ); \
- i_dump += 6; \
- break; \
-\
- case 3: \
- NeedBits( &p_adec->bit_stream, (2*6) ); \
- i_need += 12; \
- (pf_scalefactor_0)[i_sb] = pf_scalefactor[p_adec->bit_stream.fifo.buffer >> (32 - 6)]; \
- p_adec->bit_stream.fifo.buffer <<= 6; \
- (pf_scalefactor_1)[i_sb] = \
- (pf_scalefactor_2)[i_sb] = pf_scalefactor[p_adec->bit_stream.fifo.buffer >> (32 - 6)]; \
- p_adec->bit_stream.fifo.buffer <<= 6; \
- p_adec->bit_stream.fifo.i_available -= (2*6); \
- i_dump += 12; \
- break; \
- }
-/* #define SWITCH */
-
- for ( i_sb = 0; i_sb < i_bound; i_sb++ )
- {
- if ( pi_allocation_0[i_sb] )
- {
- SWITCH( pi_scfsi_0, pf_scalefactor_0_0, pf_scalefactor_0_1, pf_scalefactor_0_2 )
- }
- if ( pi_allocation_1[i_sb] )
- {
- SWITCH( pi_scfsi_1, pf_scalefactor_1_0, pf_scalefactor_1_1, pf_scalefactor_1_2 )
- }
- }
- for ( ; i_sb < i_sblimit; i_sb++ )
- {
- if ( pi_allocation_0[i_sb] )
- {
- SWITCH( pi_scfsi_0, pf_scalefactor_0_0, pf_scalefactor_0_1, pf_scalefactor_0_2 )
- SWITCH( pi_scfsi_1, pf_scalefactor_1_0, pf_scalefactor_1_1, pf_scalefactor_1_2 )
- }
- }
- for ( ; i_sb < 32; i_sb++ )
- {
- ppf_sample_0[0][i_sb] = .0;
- ppf_sample_0[1][i_sb] = .0;
- ppf_sample_0[2][i_sb] = .0;
- ppf_sample_1[0][i_sb] = .0;
- ppf_sample_1[1][i_sb] = .0;
- ppf_sample_1[2][i_sb] = .0;
- }
-
-#define NEXT_BUF \
-/* fprintf(stderr, "%p\n", p_adec->p_aout_fifo->buffer); */ \
-/* fprintf(stderr, "l_end_frame == %li, %p\n", l_end_frame, (aout_frame_t *)p_adec->p_aout_fifo->buffer + l_end_frame); */ \
- p_s16 = ((aout_frame_t *)p_adec->p_aout_fifo->buffer)[ l_end_frame ]; \
-/* fprintf(stderr, "p_s16 == %p\n", p_s16); */ \
- l_end_frame += 1; \
- l_end_frame &= AOUT_FIFO_SIZE;
-/* #define NEXT_BUF */
-
-#define GROUPTEST( pp_requantization, ppf_sample, pf_sf ) \
- requantization = *((pp_requantization)[i_sb]); \
- if ( requantization.pf_ungroup == NULL ) \
- { \
- NeedBits( &p_adec->bit_stream, requantization.i_bits_per_codeword ); \
- i_need += requantization.i_bits_per_codeword; \
- (ppf_sample)[0][i_sb] = (f_scalefactor_0 = (pf_sf)[i_sb]) * (requantization.f_slope * \
- (p_adec->bit_stream.fifo.buffer >> (32 - requantization.i_bits_per_codeword)) + requantization.f_offset); \
- DumpBits( &p_adec->bit_stream, requantization.i_bits_per_codeword ); \
- i_dump += requantization.i_bits_per_codeword; \
-\
- NeedBits( &p_adec->bit_stream, requantization.i_bits_per_codeword ); \
- i_need += requantization.i_bits_per_codeword; \
- (ppf_sample)[1][i_sb] = f_scalefactor_0 * (requantization.f_slope * \
- (p_adec->bit_stream.fifo.buffer >> (32 - requantization.i_bits_per_codeword)) + requantization.f_offset); \
- DumpBits( &p_adec->bit_stream, requantization.i_bits_per_codeword ); \
- i_dump += requantization.i_bits_per_codeword; \
-\
- NeedBits( &p_adec->bit_stream, requantization.i_bits_per_codeword ); \
- i_need += requantization.i_bits_per_codeword; \
- (ppf_sample)[2][i_sb] = f_scalefactor_0 * (requantization.f_slope * \
- (p_adec->bit_stream.fifo.buffer >> (32 - requantization.i_bits_per_codeword)) + requantization.f_offset); \
- DumpBits( &p_adec->bit_stream, requantization.i_bits_per_codeword ); \
- i_dump += requantization.i_bits_per_codeword; \
- } \
- else \
- { \
- NeedBits( &p_adec->bit_stream, requantization.i_bits_per_codeword ); \
- i_need += requantization.i_bits_per_codeword; \
- pf_ungroup = requantization.pf_ungroup + 3 * \
- (p_adec->bit_stream.fifo.buffer >> (32 - requantization.i_bits_per_codeword)); \
- DumpBits( &p_adec->bit_stream, requantization.i_bits_per_codeword ); \
- i_dump += requantization.i_bits_per_codeword; \
- (ppf_sample)[0][i_sb] = (f_scalefactor_0 = (pf_sf)[i_sb]) * pf_ungroup[0]; \
- (ppf_sample)[1][i_sb] = f_scalefactor_0 * pf_ungroup[1]; \
- (ppf_sample)[2][i_sb] = f_scalefactor_0 * pf_ungroup[2]; \
- }
-/* #define GROUPTEST */
-
-#define READ_SAMPLE_L2S( pf_scalefactor_0, pf_scalefactor_1, i_grlimit ) \
- for ( ; i_gr < (i_grlimit); i_gr++ ) \
- { \
- for ( i_sb = 0; i_sb < i_bound; i_sb++ ) \
- { \
- if ( pi_allocation_0[i_sb] ) \
- { \
- GROUPTEST( pp_requantization_0, ppf_sample_0, (pf_scalefactor_0) ) \
- } \
- if ( pi_allocation_1[i_sb] ) \
- { \
- GROUPTEST( pp_requantization_1, ppf_sample_1, (pf_scalefactor_1) ) \
- } \
- } \
- for ( ; i_sb < i_sblimit; i_sb++ ) \
- { \
- if ( pi_allocation_0[i_sb] ) \
- { \
- requantization = *(pp_requantization_0[i_sb]); \
- if ( requantization.pf_ungroup == NULL ) \
- { \
- NeedBits( &p_adec->bit_stream, requantization.i_bits_per_codeword ); \
- i_need += requantization.i_bits_per_codeword; \
- ppf_sample_0[0][i_sb] = (f_scalefactor_0 = (pf_scalefactor_0)[i_sb]) * \
- (requantization.f_slope * (f_dummy = \
- (float)(p_adec->bit_stream.fifo.buffer >> (32 - requantization.i_bits_per_codeword))) + \
- requantization.f_offset); \
- DumpBits( &p_adec->bit_stream, requantization.i_bits_per_codeword ); \
- i_dump += requantization.i_bits_per_codeword; \
- ppf_sample_1[0][i_sb] = (f_scalefactor_1 = (pf_scalefactor_1)[i_sb]) * \
- (requantization.f_slope * f_dummy + requantization.f_offset); \
-\
- NeedBits( &p_adec->bit_stream, requantization.i_bits_per_codeword ); \
- i_need += requantization.i_bits_per_codeword; \
- ppf_sample_0[1][i_sb] = f_scalefactor_0 * \
- (requantization.f_slope * (f_dummy = \
- (float)(p_adec->bit_stream.fifo.buffer >> (32 - requantization.i_bits_per_codeword))) + \
- requantization.f_offset); \
- DumpBits( &p_adec->bit_stream, requantization.i_bits_per_codeword ); \
- i_dump += requantization.i_bits_per_codeword; \
- ppf_sample_1[1][i_sb] = f_scalefactor_1 * \
- (requantization.f_slope * f_dummy + requantization.f_offset); \
-\
- NeedBits( &p_adec->bit_stream, requantization.i_bits_per_codeword ); \
- i_need += requantization.i_bits_per_codeword; \
- ppf_sample_0[2][i_sb] = f_scalefactor_0 * \
- (requantization.f_slope * (f_dummy = \
- (float)(p_adec->bit_stream.fifo.buffer >> (32 - requantization.i_bits_per_codeword))) + \
- requantization.f_offset); \
- DumpBits( &p_adec->bit_stream, requantization.i_bits_per_codeword ); \
- i_dump += requantization.i_bits_per_codeword; \
- ppf_sample_1[2][i_sb] = f_scalefactor_1 * \
- (requantization.f_slope * f_dummy + requantization.f_offset); \
- } \
- else \
- { \
- NeedBits( &p_adec->bit_stream, requantization.i_bits_per_codeword ); \
- i_need += requantization.i_bits_per_codeword; \
- pf_ungroup = requantization.pf_ungroup + 3 * \
- (p_adec->bit_stream.fifo.buffer >> (32 - requantization.i_bits_per_codeword)); \
- DumpBits( &p_adec->bit_stream, requantization.i_bits_per_codeword ); \
- i_dump += requantization.i_bits_per_codeword; \
-\
- ppf_sample_0[0][i_sb] = (f_scalefactor_0 = (pf_scalefactor_0)[i_sb]) * pf_ungroup[0]; \
- ppf_sample_0[1][i_sb] = f_scalefactor_0 * pf_ungroup[1]; \
- ppf_sample_0[2][i_sb] = f_scalefactor_0 * pf_ungroup[2]; \
-\
- ppf_sample_1[0][i_sb] = (f_scalefactor_1 = (pf_scalefactor_1)[i_sb]) * pf_ungroup[0]; \
- ppf_sample_1[1][i_sb] = f_scalefactor_1 * pf_ungroup[1]; \
- ppf_sample_1[2][i_sb] = f_scalefactor_1 * pf_ungroup[2]; \
- } \
- } \
- } \
-\
-/* fprintf(stderr, "%p", p_s16); */ \
- DCT32( ppf_sample_0[0], &p_adec->bank_0 ); \
- PCM( &p_adec->bank_0, &p_s16, 2 ); \
-/* fprintf(stderr, " %p", p_s16); */ \
- p_s16 -= 63; \
-/* fprintf(stderr, " %p\n", p_s16); */ \
-\
-/* fprintf(stderr, "%p", p_s16); */ \
- DCT32( ppf_sample_1[0], &p_adec->bank_1 ); \
- PCM( &p_adec->bank_1, &p_s16, 2 ); \
-/* fprintf(stderr, " %p", p_s16); */ \
- p_s16 -= 1; \
-/* fprintf(stderr, " %p\n", p_s16); */ \
-\
-/* fprintf(stderr, "%p", p_s16); */ \
- DCT32( ppf_sample_0[1], &p_adec->bank_0 ); \
- PCM( &p_adec->bank_0, &p_s16, 2 ); \
-/* fprintf(stderr, " %p", p_s16); */ \
- p_s16 -= 63; \
-/* fprintf(stderr, " %p\n", p_s16); */ \
-\
-/* fprintf(stderr, "%p", p_s16); */ \
- DCT32( ppf_sample_1[1], &p_adec->bank_1 ); \
- PCM( &p_adec->bank_1, &p_s16, 2 ); \
-/* fprintf(stderr, " %p", p_s16); */ \
- p_s16 -= 1; \
-/* fprintf(stderr, " %p\n", p_s16); */ \
-\
-/* fprintf(stderr, "%p", p_s16); */ \
- DCT32( ppf_sample_0[2], &p_adec->bank_0 ); \
- PCM( &p_adec->bank_0, &p_s16, 2 ); \
-/* fprintf(stderr, " %p", p_s16); */ \
- p_s16 -= 63; \
-/* fprintf(stderr, " %p\n", p_s16); */ \
-\
-/* fprintf(stderr, "%p", p_s16); */ \
- DCT32( ppf_sample_1[2], &p_adec->bank_1 ); \
- PCM( &p_adec->bank_1, &p_s16, 2 ); \
-/* fprintf(stderr, " %p", p_s16); */ \
- p_s16 -= 1; \
-/* fprintf(stderr, " %p\n", p_s16); */ \
- }
-/* #define READ_SAMPLE_L2S */
-
- l_end_frame = p_adec->p_aout_fifo->l_end_frame;
- i_gr = 0;
-
- NEXT_BUF
- READ_SAMPLE_L2S( pf_scalefactor_0_0, pf_scalefactor_1_0, 2 )
-
- NEXT_BUF
- READ_SAMPLE_L2S( pf_scalefactor_0_0, pf_scalefactor_1_0, 4 )
-
- NEXT_BUF
- READ_SAMPLE_L2S( pf_scalefactor_0_1, pf_scalefactor_1_1, 6 )
-
- NEXT_BUF
- READ_SAMPLE_L2S( pf_scalefactor_0_1, pf_scalefactor_1_1, 8 )
-
- NEXT_BUF
- READ_SAMPLE_L2S( pf_scalefactor_0_2, pf_scalefactor_1_2, 10 )
-
- NEXT_BUF
- READ_SAMPLE_L2S( pf_scalefactor_0_2, pf_scalefactor_1_2, 12 )
-
-// fprintf(stderr, "adec debug: layer == %i, padding_bit == %i, sampling_frequency == %i, bitrate_index == %i\n",
-// (i_header & ADEC_HEADER_LAYER_MASK) >> ADEC_HEADER_LAYER_SHIFT,
-// (i_header & ADEC_HEADER_PADDING_BIT_MASK) >> ADEC_HEADER_PADDING_BIT_SHIFT,
-// (i_header & ADEC_HEADER_SAMPLING_FREQUENCY_MASK) >> ADEC_HEADER_SAMPLING_FREQUENCY_SHIFT,
-// (i_header & ADEC_HEADER_BITRATE_INDEX_MASK) >> ADEC_HEADER_BITRATE_INDEX_SHIFT);
-// fprintf(stderr, "adec debug: framesize == %i, i_need == %i, i_dump == %i\n",
-// pi_framesize[ 128 * ((i_header & ADEC_HEADER_LAYER_MASK) >> ADEC_HEADER_LAYER_SHIFT) +
-// 64 * ((i_header & ADEC_HEADER_PADDING_BIT_MASK) >> ADEC_HEADER_PADDING_BIT_SHIFT) +
-// 16 * ((i_header & ADEC_HEADER_SAMPLING_FREQUENCY_MASK) >> ADEC_HEADER_SAMPLING_FREQUENCY_SHIFT) +
-// 1 * ((i_header & ADEC_HEADER_BITRATE_INDEX_MASK) >> ADEC_HEADER_BITRATE_INDEX_SHIFT) ],
-// i_need,
-// i_dump);
- p_adec->bit_stream.fifo.buffer = 0;
- p_adec->bit_stream.fifo.i_available = 0;
- return( 6 );
-}
-
-/******************************************************************************
+/*****************************************************************************
* InitThread : initialize an audio decoder thread
- ******************************************************************************
+ *****************************************************************************
* This function is called from RunThread and performs the second step of the
* initialization. It returns 0 on success.
- ******************************************************************************/
-static int InitThread( adec_thread_t * p_adec )
+ *****************************************************************************/
+static int InitThread (adec_thread_t * p_adec)
{
- aout_fifo_t aout_fifo;
-
- intf_DbgMsg("adec debug: initializing audio decoder thread %p\n", p_adec);
-
- /* Our first job is to initialize the bit stream structure with the
- * beginning of the input stream */
- pthread_mutex_lock( &p_adec->fifo.data_lock );
- while ( DECODER_FIFO_ISEMPTY(p_adec->fifo) )
- {
- pthread_cond_wait( &p_adec->fifo.data_wait, &p_adec->fifo.data_lock );
- }
- p_adec->bit_stream.p_ts = DECODER_FIFO_START( p_adec->fifo )->p_first_ts;
- p_adec->bit_stream.i_byte = p_adec->bit_stream.p_ts->i_payload_start;
- pthread_mutex_unlock( &p_adec->fifo.data_lock );
-
- /* Now we look for an audio frame header in the input stream */
- if ( FindHeader(p_adec) )
- {
- return( -1 ); /* b_die or b_error is set */
- }
-
- /*
- * We have the header and all its informations : we must be able to create
- * the audio output fifo.
- */
-
- /* Is the sound in mono mode or stereo mode ? */
- if ( (p_adec->bit_stream.fifo.buffer & ADEC_HEADER_MODE_MASK) == ADEC_HEADER_MODE_MASK )
- {
- intf_DbgMsg("adec debug: mode == mono\n");
- aout_fifo.i_type = AOUT_ADEC_MONO_FIFO;
- aout_fifo.b_stereo = 0;
- }
- else
- {
- intf_DbgMsg("adec debug: mode == stereo\n");
- aout_fifo.i_type = AOUT_ADEC_STEREO_FIFO;
- aout_fifo.b_stereo = 1;
- }
-
- /* Checking the sampling frequency */
- switch ( (p_adec->bit_stream.fifo.buffer & ADEC_HEADER_SAMPLING_FREQUENCY_MASK) \
- >> ADEC_HEADER_SAMPLING_FREQUENCY_SHIFT )
- {
- case 0:
- intf_DbgMsg("adec debug: sampling_frequency == 44100 Hz\n");
- aout_fifo.l_rate = 44100;
- break;
+ intf_DbgMsg ("adec debug: initializing audio decoder thread %p", p_adec);
- case 1:
- intf_DbgMsg("adec debug: sampling_frequency == 48000 Hz\n");
- aout_fifo.l_rate = 48000;
- break;
-
- case 2:
- intf_DbgMsg("adec debug: sampling_frequency == 32000 Hz\n");
- aout_fifo.l_rate = 32000;
- break;
-
- case 3:
- intf_ErrMsg("adec error: can't create audio output fifo (sampling_frequency == `reserved')\n");
- return( -1 );
- }
+ p_adec->p_config->decoder_config.pf_init_bit_stream( &p_adec->bit_stream,
+ p_adec->p_config->decoder_config.p_decoder_fifo, NULL, NULL );
/* Creating the audio output fifo */
- if ( (p_adec->p_aout_fifo = aout_CreateFifo(p_adec->p_aout, &aout_fifo)) == NULL )
+ p_adec->p_aout_fifo = aout_CreateFifo( AOUT_ADEC_STEREO_FIFO, 2, 0, 0,
+ ADEC_FRAME_SIZE, NULL );
+ if ( p_adec->p_aout_fifo == NULL )
{
- return( -1 );
+ return -1;
}
- intf_DbgMsg("adec debug: audio decoder thread %p initialized\n", p_adec);
- return( 0 );
+ intf_DbgMsg ( "adec debug: audio decoder thread %p initialized", p_adec );
+ return 0;
}
-/******************************************************************************
+/*****************************************************************************
* RunThread : audio decoder thread
- ******************************************************************************
+ *****************************************************************************
* Audio decoder thread. This function does only returns when the thread is
* terminated.
- ******************************************************************************/
-static void RunThread( adec_thread_t * p_adec )
+ *****************************************************************************/
+static void RunThread (adec_thread_t * p_adec)
{
-// static const int pi_framesize[512] = ADEC_FRAME_SIZE;
-// int i_header;
-// int i_framesize;
-// int i_dummy;
- mtime_t adec_date = 0;
+ int sync;
- intf_DbgMsg("adec debug: running audio decoder thread (%p) (pid == %i)\n", p_adec, getpid());
+ intf_DbgMsg ( "adec debug: running audio decoder thread (%p) (pid == %i)",
+ p_adec, getpid() );
/* Initializing the audio decoder thread */
- if ( InitThread(p_adec) )
- {
- p_adec->b_error = 1;
- }
+ p_adec->p_fifo->b_error = InitThread (p_adec);
+
+ sync = 0;
/* Audio decoder thread's main loop */
- while ( (!p_adec->b_die) && (!p_adec->b_error) )
+ while( (!p_adec->p_fifo->b_die) && (!p_adec->p_fifo->b_error) )
{
- switch ( (p_adec->bit_stream.fifo.buffer & ADEC_HEADER_LAYER_MASK) >> ADEC_HEADER_LAYER_SHIFT )
- {
- case 0:
- intf_DbgMsg("adec debug: layer == 0 (reserved)\n");
- p_adec->bit_stream.fifo.buffer = 0;
- p_adec->bit_stream.fifo.i_available = 0;
- break;
-
- case 1:
- p_adec->bit_stream.fifo.buffer = 0;
- p_adec->bit_stream.fifo.i_available = 0;
- break;
+ s16 * buffer;
+ adec_sync_info_t sync_info;
- case 2:
- if ( (p_adec->bit_stream.fifo.buffer & ADEC_HEADER_MODE_MASK) == ADEC_HEADER_MODE_MASK )
- {
- adec_Layer2_Mono( p_adec );
- }
- else
- {
-// i_header = p_adec->bit_stream.fifo.buffer;
-// i_framesize = pi_framesize[ 128*((i_header & ADEC_HEADER_LAYER_MASK) >> ADEC_HEADER_LAYER_SHIFT) +
-// 64*((i_header & ADEC_HEADER_PADDING_BIT_MASK) >> ADEC_HEADER_PADDING_BIT_SHIFT) +
-// 16*((i_header & ADEC_HEADER_SAMPLING_FREQUENCY_MASK) >> ADEC_HEADER_SAMPLING_FREQUENCY_SHIFT) +
-// 1*((i_header & ADEC_HEADER_BITRATE_INDEX_MASK) >> ADEC_HEADER_BITRATE_INDEX_SHIFT) ];
-// for ( i_dummy = 0; i_dummy < i_framesize; i_dummy++ )
-// {
-// GetByte( &p_adec->bit_stream );
-// }
-// for ( i_dummy = 0; i_dummy < 512; i_dummy++ )
-// {
-// p_adec->bank_0.v1[ i_dummy ] = .0;
-// p_adec->bank_1.v1[ i_dummy ] = .0;
-// p_adec->bank_0.v2[ i_dummy ] = .0;
-// p_adec->bank_1.v2[ i_dummy ] = .0;
-// }
+ if( DECODER_FIFO_START( *p_adec->p_fifo)->i_pts )
+ {
+ p_adec->p_aout_fifo->date[p_adec->p_aout_fifo->l_end_frame] =
+ DECODER_FIFO_START( *p_adec->p_fifo )->i_pts;
+ DECODER_FIFO_START(*p_adec->p_fifo)->i_pts = 0;
+ }
+ else
+ {
+ p_adec->p_aout_fifo->date[p_adec->p_aout_fifo->l_end_frame] =
+ LAST_MDATE;
+ }
- pthread_mutex_lock( &p_adec->p_aout_fifo->data_lock );
- while ( (((p_adec->p_aout_fifo->l_end_frame + 6) - p_adec->p_aout_fifo->l_start_frame) & AOUT_FIFO_SIZE) < 6 ) /* !! */
- {
- pthread_cond_wait( &p_adec->p_aout_fifo->data_wait, &p_adec->p_aout_fifo->data_lock );
- }
- pthread_mutex_unlock( &p_adec->p_aout_fifo->data_lock );
+ if( ! adec_SyncFrame (p_adec, &sync_info) )
+ {
+ sync = 1;
- if ( adec_Layer2_Stereo(p_adec) )
- {
- pthread_mutex_lock( &p_adec->p_aout_fifo->data_lock );
- /* Frame 1 */
- p_adec->p_aout_fifo->date[p_adec->p_aout_fifo->l_end_frame] = adec_date;
- p_adec->p_aout_fifo->l_end_frame += 1;
- p_adec->p_aout_fifo->l_end_frame &= AOUT_FIFO_SIZE;
- /* Frame 2 */
- p_adec->p_aout_fifo->date[p_adec->p_aout_fifo->l_end_frame] = LAST_MDATE;
- p_adec->p_aout_fifo->l_end_frame += 1;
- p_adec->p_aout_fifo->l_end_frame &= AOUT_FIFO_SIZE;
- /* Frame 3 */
- p_adec->p_aout_fifo->date[p_adec->p_aout_fifo->l_end_frame] = LAST_MDATE;
- p_adec->p_aout_fifo->l_end_frame += 1;
- p_adec->p_aout_fifo->l_end_frame &= AOUT_FIFO_SIZE;
- /* Frame 4 */
- p_adec->p_aout_fifo->date[p_adec->p_aout_fifo->l_end_frame] = LAST_MDATE;
- p_adec->p_aout_fifo->l_end_frame += 1;
- p_adec->p_aout_fifo->l_end_frame &= AOUT_FIFO_SIZE;
- /* Frame 5 */
- p_adec->p_aout_fifo->date[p_adec->p_aout_fifo->l_end_frame] = LAST_MDATE;
- p_adec->p_aout_fifo->l_end_frame += 1;
- p_adec->p_aout_fifo->l_end_frame &= AOUT_FIFO_SIZE;
- /* Frame 6 */
- p_adec->p_aout_fifo->date[p_adec->p_aout_fifo->l_end_frame] = LAST_MDATE;
- p_adec->p_aout_fifo->l_end_frame += 1;
- p_adec->p_aout_fifo->l_end_frame &= AOUT_FIFO_SIZE;
- pthread_mutex_unlock( &p_adec->p_aout_fifo->data_lock );
- adec_date += 24000; /* !! */
- }
- }
- break;
+ p_adec->p_aout_fifo->l_rate = sync_info.sample_rate;
- case 3:
- if ( (p_adec->bit_stream.fifo.buffer & ADEC_HEADER_MODE_MASK) == ADEC_HEADER_MODE_MASK )
- {
- adec_Layer1_Mono( p_adec );
- }
- else
- {
- adec_Layer1_Stereo( p_adec );
- }
- break;
+ buffer = ((s16 *)p_adec->p_aout_fifo->buffer)
+ + (p_adec->p_aout_fifo->l_end_frame * ADEC_FRAME_SIZE);
- default:
- intf_DbgMsg("adec debug: layer == %i (unknown)\n",
- (p_adec->bit_stream.fifo.buffer & ADEC_HEADER_LAYER_MASK) >> ADEC_HEADER_LAYER_SHIFT);
- p_adec->bit_stream.fifo.buffer = 0;
- p_adec->bit_stream.fifo.i_available = 0;
- break;
+ if( adec_DecodeFrame (p_adec, buffer) )
+ {
+ /* Ouch, failed decoding... We'll have to resync */
+ sync = 0;
+ }
+ else
+ {
+ vlc_mutex_lock (&p_adec->p_aout_fifo->data_lock);
+
+ p_adec->p_aout_fifo->l_end_frame =
+ (p_adec->p_aout_fifo->l_end_frame + 1) & AOUT_FIFO_SIZE;
+ vlc_cond_signal (&p_adec->p_aout_fifo->data_wait);
+ vlc_mutex_unlock (&p_adec->p_aout_fifo->data_lock);
+ }
}
- FindHeader( p_adec );
}
/* If b_error is set, the audio decoder thread enters the error loop */
- if ( p_adec->b_error )
+ if( p_adec->p_fifo->b_error )
{
ErrorThread( p_adec );
}
EndThread( p_adec );
}
-/******************************************************************************
+/*****************************************************************************
* ErrorThread : audio decoder's RunThread() error loop
- ******************************************************************************
+ *****************************************************************************
* This function is called when an error occured during thread main's loop. The
* thread can still receive feed, but must be ready to terminate as soon as
* possible.
- ******************************************************************************/
-static void ErrorThread( adec_thread_t *p_adec )
+ *****************************************************************************/
+static void ErrorThread ( adec_thread_t *p_adec )
{
/* We take the lock, because we are going to read/write the start/end
* indexes of the decoder fifo */
- pthread_mutex_lock( &p_adec->fifo.data_lock );
+ vlc_mutex_lock ( &p_adec->p_fifo->data_lock );
/* Wait until a `die' order is sent */
- while( !p_adec->b_die )
+ while ( !p_adec->p_fifo->b_die )
{
/* Trash all received PES packets */
- while( !DECODER_FIFO_ISEMPTY(p_adec->fifo) )
+ while ( !DECODER_FIFO_ISEMPTY(*p_adec->p_fifo) )
{
- input_NetlistFreePES( p_adec->bit_stream.p_input, DECODER_FIFO_START(p_adec->fifo) );
- DECODER_FIFO_INCSTART( p_adec->fifo );
-#ifdef DEBUG
-// fprintf(stderr, "*");
-#endif
+ p_adec->p_fifo->pf_delete_pes ( p_adec->p_fifo->p_packets_mgt,
+ DECODER_FIFO_START(*p_adec->p_fifo) );
+ DECODER_FIFO_INCSTART ( *p_adec->p_fifo );
}
/* Waiting for the input thread to put new PES packets in the fifo */
- pthread_cond_wait( &p_adec->fifo.data_wait, &p_adec->fifo.data_lock );
+ vlc_cond_wait ( &p_adec->p_fifo->data_wait, &p_adec->p_fifo->data_lock );
}
/* We can release the lock before leaving */
- pthread_mutex_unlock( &p_adec->fifo.data_lock );
+ vlc_mutex_unlock ( &p_adec->p_fifo->data_lock );
}
-/******************************************************************************
+/*****************************************************************************
* EndThread : audio decoder thread destruction
- ******************************************************************************
- * This function is called when the thread ends after a sucessfull
+ *****************************************************************************
+ * This function is called when the thread ends after a sucessful
* initialization.
- ******************************************************************************/
-static void EndThread( adec_thread_t *p_adec )
+ *****************************************************************************/
+static void EndThread ( adec_thread_t *p_adec )
{
- intf_DbgMsg("adec debug: destroying audio decoder thread %p\n", p_adec);
+ intf_DbgMsg ( "adec debug: destroying audio decoder thread %p", p_adec );
/* If the audio output fifo was created, we destroy it */
- if ( p_adec->p_aout_fifo != NULL )
+ if ( p_adec->p_aout_fifo != NULL )
{
- aout_DestroyFifo( p_adec->p_aout_fifo );
+ aout_DestroyFifo ( p_adec->p_aout_fifo );
+
+ /* Make sure the output thread leaves the NextFrame() function */
+ vlc_mutex_lock (&(p_adec->p_aout_fifo->data_lock));
+ vlc_cond_signal (&(p_adec->p_aout_fifo->data_wait));
+ vlc_mutex_unlock (&(p_adec->p_aout_fifo->data_lock));
}
/* Destroy descriptor */
+ free( p_adec->p_config );
free( p_adec );
- intf_DbgMsg("adec debug: audio decoder thread %p destroyed\n", p_adec);
+ intf_DbgMsg ("adec debug: audio decoder thread %p destroyed", p_adec);
}
+