Commit e3636eb1 authored by Sam Hocevar's avatar Sam Hocevar

  . moved the MPEG audio decoder to the new bitstream

    I wasn't sure whether the bits counting method was effective to
  skip ancillary data at the end of a frame, but I kept it for
  safety. There is still a lot to optimize in the bit counting, like
  unrolling the first iteration of some loops, but I don't know if
  it would be worth it. The other solution would have been to look for
  a startcode after eache frame, without caring about the ancillary bits.

  . cleaning in the SPU decoder.
parent 993381a2
...@@ -49,7 +49,7 @@ ...@@ -49,7 +49,7 @@
* order to avoid rounding problems and heavy computations, as the function * order to avoid rounding problems and heavy computations, as the function
* that handles this structure only uses additions. * that handles this structure only uses additions.
*****************************************************************************/ *****************************************************************************/
typedef struct typedef struct aout_increment_s
{ {
/* The remainder is used to keep track of the fractional part of the /* The remainder is used to keep track of the fractional part of the
* index. */ * index. */
...@@ -73,7 +73,7 @@ typedef struct ...@@ -73,7 +73,7 @@ typedef struct
/***************************************************************************** /*****************************************************************************
* aout_fifo_t * aout_fifo_t
*****************************************************************************/ *****************************************************************************/
typedef struct typedef struct aout_fifo_s
{ {
/* See the fifo types below */ /* See the fifo types below */
int i_type; int i_type;
......
/*****************************************************************************
* audio_bit_stream.h: getbits functions for the audio decoder
*****************************************************************************
* Copyright (C) 2000 VideoLAN
*
* Authors:
*
* 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.
*****************************************************************************/
static __inline__ u8 GetByte (adec_bit_stream_t * p_bit_stream)
{
/* Are there some bytes left in the current buffer ? */
if (p_bit_stream->byte_stream.p_byte >= p_bit_stream->byte_stream.p_end) {
/* no, switch to next buffer */
adec_byte_stream_next (&p_bit_stream->byte_stream);
}
p_bit_stream->total_bytes_read++;
return *(p_bit_stream->byte_stream.p_byte++);
}
static __inline__ void NeedBits (adec_bit_stream_t * p_bit_stream, int i_bits)
{
while (p_bit_stream->i_available < i_bits) {
p_bit_stream->buffer |=
((u32)GetByte (p_bit_stream)) << (24 - p_bit_stream->i_available);
p_bit_stream->i_available += 8;
}
}
static __inline__ void DumpBits (adec_bit_stream_t * p_bit_stream, int i_bits)
{
p_bit_stream->buffer <<= i_bits;
p_bit_stream->i_available -= i_bits;
}
...@@ -20,17 +20,22 @@ ...@@ -20,17 +20,22 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/ *****************************************************************************/
#include "int_types.h" #include "defs.h"
#include "config.h"
#include "common.h"
#include "threads.h"
#include "mtime.h"
#include "stream_control.h"
#include "input_ext-dec.h"
#include "adec_generic.h" #include "adec_generic.h"
#include "audio_decoder.h"
#include "adec_math.h" /* DCT32(), PCM() */ #include "adec_math.h" /* DCT32(), PCM() */
#include "adec_bit_stream.h"
#include "adec_layer1.h" #include "adec_layer1.h"
#include "adec_layer2.h" #include "adec_layer2.h"
#define NULL ((void *)0) int adec_Init( adec_thread_t * p_adec )
int adec_init (audiodec_t * p_adec)
{ {
p_adec->bank_0.actual = p_adec->bank_0.v1; p_adec->bank_0.actual = p_adec->bank_0.v1;
p_adec->bank_0.pos = 0; p_adec->bank_0.pos = 0;
...@@ -39,7 +44,7 @@ int adec_init (audiodec_t * p_adec) ...@@ -39,7 +44,7 @@ int adec_init (audiodec_t * p_adec)
return 0; return 0;
} }
int adec_sync_frame (audiodec_t * p_adec, adec_sync_info_t * p_sync_info) int adec_SyncFrame( adec_thread_t * p_adec, adec_sync_info_t * p_sync_info )
{ {
static int mpeg1_sample_rate[3] = {44100, 48000, 32000}; static int mpeg1_sample_rate[3] = {44100, 48000, 32000};
static int mpeg1_layer1_bit_rate[15] = static int mpeg1_layer1_bit_rate[15] =
...@@ -71,49 +76,47 @@ int adec_sync_frame (audiodec_t * p_adec, adec_sync_info_t * p_sync_info) ...@@ -71,49 +76,47 @@ int adec_sync_frame (audiodec_t * p_adec, adec_sync_info_t * p_sync_info)
int bit_rate; int bit_rate;
int frame_size; int frame_size;
p_adec->bit_stream.total_bytes_read = 0; /* We read the whole header, but only really take 8 bits */
header = GetBits( &p_adec->bit_stream, 8 ) << 24;
header |= ShowBits( &p_adec->bit_stream, 24 );
header = GetByte (&p_adec->bit_stream) << 24;
header |= GetByte (&p_adec->bit_stream) << 16;
header |= GetByte (&p_adec->bit_stream) << 8;
header |= GetByte (&p_adec->bit_stream);
p_adec->header = header; p_adec->header = header;
/* basic header check : sync word, no emphasis */ /* basic header check : sync word, no emphasis */
if ((header & 0xfff00003) != 0xfff00000) if( (header & 0xfff00003) != 0xfff00000 )
{ {
return 1; return 1;
} }
/* calculate bit rate */ /* calculate bit rate */
index = (header >> 17) & 7; /* mpeg ID + layer */ index = ( header >> 17 ) & 7; /* mpeg ID + layer */
bit_rates = bit_rate_table[index]; bit_rates = bit_rate_table[ index ];
if (bit_rate_table == NULL) if( bit_rate_table == NULL )
{ {
return 1; /* invalid layer */ return 1; /* invalid layer */
} }
index = (header >> 12) & 15; /* bit rate index */ index = ( header >> 12 ) & 15; /* bit rate index */
if (index > 14) if (index > 14)
{ {
return 1; return 1;
} }
bit_rate = bit_rates[index]; bit_rate = bit_rates[ index ];
/* mpeg 1 layer 2 : check that bitrate per channel is valid */ /* mpeg 1 layer 2 : check that bitrate per channel is valid */
if (bit_rates == mpeg1_layer2_bit_rate) if( bit_rates == mpeg1_layer2_bit_rate )
{ {
if ((header & 0xc0) == 0xc0) if( (header & 0xc0) == 0xc0 )
{ /* mono */ { /* mono */
if (index > 10) if( index > 10 )
{ {
return 1; /* invalid bitrate per channel */ return 1; /* invalid bitrate per channel */
} }
} }
else else
{ /* stereo */ { /* stereo */
if ((1 << index) & 0x2e) if( (1 << index) & 0x2e )
{ {
return 1; /* invalid bitrate per channel */ return 1; /* invalid bitrate per channel */
} }
...@@ -122,37 +125,48 @@ int adec_sync_frame (audiodec_t * p_adec, adec_sync_info_t * p_sync_info) ...@@ -122,37 +125,48 @@ int adec_sync_frame (audiodec_t * p_adec, adec_sync_info_t * p_sync_info)
/* calculate sample rate */ /* calculate sample rate */
index = (header >> 10) & 3; /* sample rate index */ index = ( header >> 10 ) & 3; /* sample rate index */
if (index > 2) if( index > 2 )
{ {
return 1; return 1;
} }
sample_rate = mpeg1_sample_rate[index]; sample_rate = mpeg1_sample_rate[ index ];
if (!(header & 0x80000))
if( ! (header & 0x80000) )
{ {
sample_rate >>= 1; /* half sample rate for mpeg2 */ sample_rate >>= 1; /* half sample rate for mpeg2 */
} }
/* calculate frame length */ /* calculate frame length */
if ((header & 0x60000) == 0x60000) if( (header & 0x60000) == 0x60000 )
{ /* layer 1 */ {
/* layer 1 */
frame_size = 48000 * bit_rate / sample_rate; frame_size = 48000 * bit_rate / sample_rate;
if (header & 0x200) /* padding */
/* padding */
if( header & 0x200 )
{ {
frame_size += 4; frame_size += 4;
} }
} }
else else
{ /* layer >1 */ {
/* layer >1 */
frame_size = 144000 * bit_rate / sample_rate; frame_size = 144000 * bit_rate / sample_rate;
if (header & 0x200) /* padding */
/* padding */
if( header & 0x200 )
{ {
frame_size ++; frame_size ++;
} }
} }
/* Now we are sure we want this header, read it */
RemoveBits( &p_adec->bit_stream, 24 );
p_adec->i_read_bits = 32;
p_sync_info->sample_rate = sample_rate; p_sync_info->sample_rate = sample_rate;
p_sync_info->bit_rate = bit_rate; p_sync_info->bit_rate = bit_rate;
p_sync_info->frame_size = frame_size; p_sync_info->frame_size = frame_size;
...@@ -161,77 +175,76 @@ int adec_sync_frame (audiodec_t * p_adec, adec_sync_info_t * p_sync_info) ...@@ -161,77 +175,76 @@ int adec_sync_frame (audiodec_t * p_adec, adec_sync_info_t * p_sync_info)
return 0; return 0;
} }
int adec_decode_frame (audiodec_t * p_adec, s16 * buffer) int adec_DecodeFrame( adec_thread_t * p_adec, s16 * buffer )
{ {
if (!(p_adec->header & 0x10000)) int i_total_bytes_read;
{ /* error check, skip it */
GetByte (&p_adec->bit_stream); if( ! (p_adec->header & 0x10000) )
GetByte (&p_adec->bit_stream); {
/* Error check, skip it */
RemoveBits( &p_adec->bit_stream, 16 );
p_adec->i_read_bits += 16;
} }
/* parse audio data */ /* parse audio data */
p_adec->bit_stream.i_available = 0; switch( (p_adec->header >> 17) & 3 )
switch ((p_adec->header >> 17) & 3)
{ {
case 2: /* layer 2 */ case 2:
if ((p_adec->header & 0xc0) == 0xc0) /* layer 2 */
if( (p_adec->header & 0xc0) == 0xc0 )
{
if( adec_layer2_mono (p_adec, buffer) )
{ {
if (adec_layer2_mono (p_adec, buffer)) return 1;
{
return 1;
}
} }
else }
else
{
if( adec_layer2_stereo (p_adec, buffer) )
{ {
if (adec_layer2_stereo (p_adec, buffer)) return 1;
{
return 1;
}
} }
}
break; break;
case 3: /* layer 1 */ case 3:
if ((p_adec->header & 0xc0) == 0xc0) /* layer 1 */
if( (p_adec->header & 0xc0) == 0xc0 )
{
if( adec_layer1_mono (p_adec, buffer) )
{ {
if (adec_layer1_mono (p_adec, buffer)) return 1;
{
return 1;
}
} }
else }
else
{
if( adec_layer1_stereo (p_adec, buffer) )
{ {
if (adec_layer1_stereo (p_adec, buffer)) return 1;
{
return 1;
}
} }
}
break; break;
} }
/* skip ancillary data */ /* Skip ancillary data */
if ((p_adec->header & 0xf000) == 0) /* free bitrate format */ if( (p_adec->header & 0xf000) == 0 ) /* free bitrate format */
{ {
return 0; return 0;
} }
/* XXX rewrite the byte counting system to reduce overhead */ RealignBits( &p_adec->bit_stream );
i_total_bytes_read = ( p_adec->i_read_bits + 7 ) / 8;
#if 0
intf_DbgMsg ( "skip %d",
p_adec->frame_size - p_adec->bit_stream.total_bytes_read );
#endif
if (p_adec->bit_stream.total_bytes_read > p_adec->frame_size) if( i_total_bytes_read > p_adec->frame_size )
{ {
return 1; /* overrun */ return 1; /* overrun */
} }
while (p_adec->bit_stream.total_bytes_read < p_adec->frame_size) while( i_total_bytes_read++ < p_adec->frame_size )
{ {
GetByte (&p_adec->bit_stream); /* skip ancillary data */ RemoveBits( &p_adec->bit_stream, 8 ); /* skip ancillary data */
} }
return 0; return 0;
......
...@@ -31,61 +31,12 @@ typedef struct adec_sync_info_s { ...@@ -31,61 +31,12 @@ typedef struct adec_sync_info_s {
int bit_rate; /* nominal bit rate in kbps */ int bit_rate; /* nominal bit rate in kbps */
} adec_sync_info_t; } adec_sync_info_t;
typedef struct adec_byte_stream_s { typedef struct adec_bank_s
u8 * p_byte; {
u8 * p_end;
void * info;
} adec_byte_stream_t;
/**** audio decoder API - functions publically provided by the audio dec. ****/
int adec_init (audiodec_t * p_adec);
int adec_sync_frame (audiodec_t * p_adec, adec_sync_info_t * p_sync_info);
int adec_decode_frame (audiodec_t * p_adec, s16 * buffer);
static adec_byte_stream_t * adec_byte_stream (audiodec_t * p_adec);
/**** audio decoder API - user functions to be provided to the audio dec. ****/
void adec_byte_stream_next (adec_byte_stream_t * p_byte_stream);
/**** EVERYTHING AFTER THIS POINT IS PRIVATE ! DO NOT USE DIRECTLY ****/
/**** audio decoder internal structures ****/
typedef struct adec_bank_s {
float v1[512]; float v1[512];
float v2[512]; float v2[512];
float * actual; float * actual;
int pos; int pos;
} adec_bank_t; } adec_bank_t;
typedef struct adec_bit_stream_s {
u32 buffer;
int i_available;
adec_byte_stream_t byte_stream;
int total_bytes_read;
} adec_bit_stream_t;
struct audiodec_s {
/*
* Input properties
*/
/* The bit stream structure handles the PES stream at the bit level */
adec_bit_stream_t bit_stream;
/*
* Decoder properties
*/
u32 header;
int frame_size;
adec_bank_t bank_0;
adec_bank_t bank_1;
};
/**** audio decoder inline functions ****/
static adec_byte_stream_t * adec_byte_stream (audiodec_t * p_adec)
{
return &(p_adec->bit_stream.byte_stream);
}
This diff is collapsed.
...@@ -20,6 +20,6 @@ ...@@ -20,6 +20,6 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/ *****************************************************************************/
int adec_layer1_mono( audiodec_t * p_adec, s16 * buffer ); int adec_layer1_mono( adec_thread_t * p_adec, s16 * buffer );
int adec_layer1_stereo (audiodec_t * p_adec, s16 * buffer); int adec_layer1_stereo (adec_thread_t * p_adec, s16 * buffer);
This diff is collapsed.
...@@ -20,6 +20,6 @@ ...@@ -20,6 +20,6 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/ *****************************************************************************/
int adec_layer2_mono( audiodec_t * p_adec, s16 * buffer ); int adec_layer2_mono ( adec_thread_t * p_adec, s16 * buffer );
int adec_layer2_stereo (audiodec_t * p_adec, s16 * buffer); int adec_layer2_stereo ( adec_thread_t * p_adec, s16 * buffer );
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
*****************************************************************************/ *****************************************************************************/
#include "int_types.h" #include "int_types.h"
#include "adec_generic.h" /* adec_bank_t */ #include "adec_generic.h"
/***************************************************************************** /*****************************************************************************
* DCT32: Fast 32 points Discrete Cosine Transform * DCT32: Fast 32 points Discrete Cosine Transform
......
...@@ -37,6 +37,7 @@ ...@@ -37,6 +37,7 @@
#include "int_types.h" #include "int_types.h"
#include "adec_generic.h" #include "adec_generic.h"
#include "audio_decoder.h"
#define ADEC_FRAME_SIZE (2*1152) #define ADEC_FRAME_SIZE (2*1152)
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* audio_decoder.c: MPEG audio decoder thread * audio_decoder.c: MPEG audio decoder thread
***************************************************************************** *****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN * Copyright (C) 1999, 2000 VideoLAN
* $Id: audio_decoder.c,v 1.45 2001/01/05 18:46:44 massiot Exp $ * $Id: audio_decoder.c,v 1.46 2001/01/11 17:44:48 sam Exp $
* *
* Authors: Michel Kaempf <maxx@via.ecp.fr> * Authors: Michel Kaempf <maxx@via.ecp.fr>
* Michel Lespinasse <walken@via.ecp.fr> * Michel Lespinasse <walken@via.ecp.fr>
...@@ -83,7 +83,8 @@ vlc_thread_t adec_CreateThread ( adec_config_t * p_config ) ...@@ -83,7 +83,8 @@ vlc_thread_t adec_CreateThread ( adec_config_t * p_config )
/* Allocate the memory needed to store the thread's structure */ /* 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" ); intf_ErrMsg ( "adec error: not enough memory for"
" adec_CreateThread() to create the new thread" );
return 0; return 0;
} }
...@@ -93,11 +94,10 @@ vlc_thread_t adec_CreateThread ( adec_config_t * p_config ) ...@@ -93,11 +94,10 @@ vlc_thread_t adec_CreateThread ( adec_config_t * p_config )
p_adec->p_config = p_config; p_adec->p_config = p_config;
p_adec->p_fifo = p_config->decoder_config.p_decoder_fifo; p_adec->p_fifo = p_config->decoder_config.p_decoder_fifo;
/* /*
* Initialize the decoder properties * Initialize the decoder properties
*/ */
adec_init ( &p_adec->audio_decoder ); adec_Init ( p_adec );
/* /*
* Initialize the output properties * Initialize the output properties
...@@ -106,7 +106,8 @@ vlc_thread_t adec_CreateThread ( adec_config_t * p_config ) ...@@ -106,7 +106,8 @@ vlc_thread_t adec_CreateThread ( adec_config_t * p_config )
p_adec->p_aout_fifo = NULL; p_adec->p_aout_fifo = NULL;
/* Spawn the audio decoder thread */ /* Spawn the audio decoder thread */
if ( vlc_thread_create(&p_adec->thread_id, "audio decoder", (vlc_thread_func_t)RunThread, (void *)p_adec) ) if ( vlc_thread_create(&p_adec->thread_id, "audio decoder",
(vlc_thread_func_t)RunThread, (void *)p_adec) )
{ {
intf_ErrMsg ("adec error: can't spawn audio decoder thread"); intf_ErrMsg ("adec error: can't spawn audio decoder thread");
free (p_adec); free (p_adec);
...@@ -117,6 +118,8 @@ vlc_thread_t adec_CreateThread ( adec_config_t * p_config ) ...@@ -117,6 +118,8 @@ vlc_thread_t adec_CreateThread ( adec_config_t * p_config )
return p_adec->thread_id; return p_adec->thread_id;
} }
/* following functions are local */
/***************************************************************************** /*****************************************************************************
* InitThread : initialize an audio decoder thread * InitThread : initialize an audio decoder thread
***************************************************************************** *****************************************************************************
...@@ -126,28 +129,11 @@ vlc_thread_t adec_CreateThread ( adec_config_t * p_config ) ...@@ -126,28 +129,11 @@ vlc_thread_t adec_CreateThread ( adec_config_t * p_config )
static int InitThread (adec_thread_t * p_adec) static int InitThread (adec_thread_t * p_adec)
{ {
aout_fifo_t aout_fifo; aout_fifo_t aout_fifo;
adec_byte_stream_t * byte_stream;
intf_DbgMsg ("adec debug: initializing audio decoder thread %p", p_adec); intf_DbgMsg ("adec debug: initializing audio decoder thread %p", p_adec);
/* Our first job is to initialize the bit stream structure with the p_adec->p_config->decoder_config.pf_init_bit_stream( &p_adec->bit_stream,
* beginning of the input stream */ p_adec->p_config->decoder_config.p_decoder_fifo );
vlc_mutex_lock ( &p_adec->p_fifo->data_lock );
while ( DECODER_FIFO_ISEMPTY(*p_adec->p_fifo) )
{
if (p_adec->p_fifo->b_die)
{
vlc_mutex_unlock ( &p_adec->p_fifo->data_lock );
return -1;
}
vlc_cond_wait ( &p_adec->p_fifo->data_wait, &p_adec->p_fifo->data_lock );
}
p_adec->p_data = DECODER_FIFO_START ( *p_adec->p_fifo )->p_first;
byte_stream = adec_byte_stream ( &p_adec->audio_decoder );
byte_stream->p_byte = p_adec->p_data->p_payload_start;
byte_stream->p_end = p_adec->p_data->p_payload_end;
byte_stream->info = p_adec;
vlc_mutex_unlock ( &p_adec->p_fifo->data_lock );
aout_fifo.i_type = AOUT_ADEC_STEREO_FIFO; aout_fifo.i_type = AOUT_ADEC_STEREO_FIFO;
aout_fifo.i_channels = 2; aout_fifo.i_channels = 2;
...@@ -155,7 +141,8 @@ static int InitThread (adec_thread_t * p_adec) ...@@ -155,7 +141,8 @@ static int InitThread (adec_thread_t * p_adec)
aout_fifo.l_frame_size = ADEC_FRAME_SIZE; aout_fifo.l_frame_size = ADEC_FRAME_SIZE;
/* Creating the audio output fifo */ /* Creating the audio output fifo */
if ( (p_adec->p_aout_fifo = aout_CreateFifo(p_adec->p_aout, &aout_fifo)) == NULL ) if ( (p_adec->p_aout_fifo =
aout_CreateFifo(p_adec->p_aout, &aout_fifo)) == NULL )
{ {
return -1; return -1;
} }
...@@ -174,16 +161,14 @@ static void RunThread (adec_thread_t * p_adec) ...@@ -174,16 +161,14 @@ static void RunThread (adec_thread_t * p_adec)
{ {
int sync; int sync;
intf_DbgMsg ( "adec debug: running audio decoder thread (%p) (pid == %i)", p_adec, getpid() ); intf_DbgMsg ( "adec debug: running audio decoder thread (%p) (pid == %i)",
p_adec, getpid() );
/* You really suck */ /* You really suck */
//msleep ( INPUT_PTS_DELAY ); //msleep ( INPUT_PTS_DELAY );
/* Initializing the audio decoder thread */ /* Initializing the audio decoder thread */
if( InitThread (p_adec) ) p_adec->p_fifo->b_error = InitThread (p_adec);
{
p_adec->p_fifo->b_error = 1;
}
sync = 0; sync = 0;
...@@ -193,26 +178,6 @@ static void RunThread (adec_thread_t * p_adec) ...@@ -193,26 +178,6 @@ static void RunThread (adec_thread_t * p_adec)
s16 * buffer; s16 * buffer;
adec_sync_info_t sync_info; adec_sync_info_t sync_info;
if ( !sync )
{
/* have to find a synchro point */
adec_byte_stream_t * p_byte_stream;
intf_DbgMsg ( "adec: sync" );
p_byte_stream = adec_byte_stream ( &p_adec->audio_decoder );
/* FIXME: the check will be done later, am I right ? */
/* FIXME: is this really needed ?
adec_byte_stream_next ( p_byte_stream ); */
if( p_adec->p_fifo->b_die || p_adec->p_fifo->b_error )
{
goto bad_frame;
}
}
if( DECODER_FIFO_START( *p_adec->p_fifo)->i_pts ) if( DECODER_FIFO_START( *p_adec->p_fifo)->i_pts )
{ {
p_adec->p_aout_fifo->date[p_adec->p_aout_fifo->l_end_frame] = p_adec->p_aout_fifo->date[p_adec->p_aout_fifo->l_end_frame] =
...@@ -225,32 +190,30 @@ static void RunThread (adec_thread_t * p_adec) ...@@ -225,32 +190,30 @@ static void RunThread (adec_thread_t * p_adec)
LAST_MDATE; LAST_MDATE;
} }
if( adec_sync_frame (&p_adec->audio_decoder, &sync_info) ) if( ! adec_SyncFrame (p_adec, &sync_info) )
{ {
goto bad_frame; sync = 1;
}
sync = 1;
p_adec->p_aout_fifo->l_rate = sync_info.sample_rate; p_adec->p_aout_fifo->l_rate = sync_info.sample_rate;
buffer = ((s16 *)p_adec->p_aout_fifo->buffer) buffer = ((s16 *)p_adec->p_aout_fifo->buffer)
+ (p_adec->p_aout_fifo->l_end_frame * ADEC_FRAME_SIZE); + (p_adec->p_aout_fifo->l_end_frame * ADEC_FRAME_SIZE);
if( adec_decode_frame (&p_adec->audio_decoder, buffer) ) if( adec_DecodeFrame (p_adec, buffer) )
{ {
sync = 0; /* Ouch, failed decoding... We'll have to resync */
goto bad_frame; 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);
}
} }
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);
bad_frame:
} }
/* If b_error is set, the audio decoder thread enters the error loop */ /* If b_error is set, the audio decoder thread enters the error loop */
...@@ -322,64 +285,3 @@ static void EndThread ( adec_thread_t *p_adec ) ...@@ -322,64 +285,3 @@ static void EndThread ( adec_thread_t *p_adec )
intf_DbgMsg ("adec debug: audio decoder thread %p destroyed", p_adec); intf_DbgMsg ("adec debug: audio decoder thread %p destroyed", p_adec);
} }
void adec_byte_stream_next ( adec_byte_stream_t * p_byte_stream )
{
adec_thread_t * p_adec = p_byte_stream->info;
/* 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_adec->p_data->p_next == 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 */
vlc_mutex_lock (&p_adec->p_fifo->data_lock);
/* Is the input thread dying ? */
if (p_adec->p_fifo->b_die)
{
vlc_mutex_unlock (&(p_adec->p_fifo->data_lock));
return;
}
/* 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. */
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);
while (DECODER_FIFO_ISEMPTY(*p_adec->p_fifo))
{
vlc_cond_wait (&p_adec->p_fifo->data_wait, &p_adec->p_fifo->data_lock);
if (p_adec->p_fifo->b_die)
{
vlc_mutex_unlock (&(p_adec->p_fifo->data_lock));
return;
}
}
/* The next byte could be found in the next PES packet */
p_adec->p_data = DECODER_FIFO_START (*p_adec->p_fifo)->p_first;
/* We can release the fifo's data lock */
vlc_mutex_unlock (&p_adec->p_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
{
p_adec->p_data = p_adec->p_data->p_next;
}
} while (p_adec->p_data->p_payload_start == p_adec->p_data->p_payload_end);
/* We've found a TS packet which contains interesting data... */
p_byte_stream->p_byte = p_adec->p_data->p_payload_start;
p_byte_stream->p_end = p_adec->p_data->p_payload_end;
}
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* audio_decoder.h : audio decoder thread interface * audio_decoder.h : audio decoder thread interface
***************************************************************************** *****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN * Copyright (C) 1999, 2000 VideoLAN
* $Id: audio_decoder.h,v 1.4 2001/01/05 14:45:47 sam Exp $ * $Id: audio_decoder.h,v 1.5 2001/01/11 17:44:48 sam Exp $
* *
* Authors: * Authors:
* Michel Kaempf <maxx@via.ecp.fr> * Michel Kaempf <maxx@via.ecp.fr>
...@@ -36,24 +36,33 @@ typedef struct adec_thread_s ...@@ -36,24 +36,33 @@ typedef struct adec_thread_s
* Input properties * Input properties
*/ */
decoder_fifo_t * p_fifo; /* stores the PES stream data */ decoder_fifo_t * p_fifo; /* stores the PES stream data */
data_packet_t * p_data; /* The bit stream structure handles the PES stream at the bit level */
bit_stream_t bit_stream;
int i_read_bits;
adec_config_t * p_config; adec_config_t * p_config;
/* /*
* Decoder properties * Decoder properties
*/ */
audiodec_t audio_decoder; u32 header;
int frame_size;
adec_bank_t bank_0;
adec_bank_t bank_1;
/* /*
* Output properties * Output properties
*/ */
aout_fifo_t * p_aout_fifo; /* stores the decompressed audio frames */ struct aout_fifo_s * p_aout_fifo; /* stores the decompressed frames */
aout_thread_t * p_aout; /* needed to create the audio fifo */ struct aout_thread_s * p_aout; /* needed to create the audio fifo */
} adec_thread_t; } adec_thread_t;
/***************************************************************************** /*****************************************************************************
* Prototypes * Prototypes
*****************************************************************************/ *****************************************************************************/
vlc_thread_t adec_CreateThread ( adec_config_t * p_config ); vlc_thread_t adec_CreateThread ( adec_config_t * p_config );
int adec_Init ( adec_thread_t * p_adec );
int adec_SyncFrame ( adec_thread_t * p_adec,
adec_sync_info_t * p_sync_info );
int adec_DecodeFrame ( adec_thread_t * p_adec, s16 * buffer );
...@@ -63,17 +63,18 @@ vlc_thread_t spudec_CreateThread( vdec_config_t * p_config ) ...@@ -63,17 +63,18 @@ vlc_thread_t spudec_CreateThread( vdec_config_t * p_config )
intf_DbgMsg("spudec debug: creating spu decoder thread"); intf_DbgMsg("spudec debug: creating spu decoder thread");
/* Allocate the memory needed to store the thread's structure */ /* Allocate the memory needed to store the thread's structure */
if ( (p_spudec = (spudec_thread_t *)malloc( sizeof(spudec_thread_t) )) == NULL ) p_spudec = (spudec_thread_t *)malloc( sizeof(spudec_thread_t) );
if ( p_spudec == NULL )
{ {
intf_ErrMsg("spudec error: not enough memory for spudec_CreateThread() to create the new thread"); intf_ErrMsg( "spudec error: not enough memory "
"for spudec_CreateThread() to create the new thread" );
return( 0 ); return( 0 );
} }
/* /*
* Initialize the thread properties * Initialize the thread properties
*/ */
p_spudec->p_fifo->b_die = 0;
p_spudec->p_fifo->b_error = 0;
p_spudec->p_config = p_config; p_spudec->p_config = p_config;
p_spudec->p_fifo = p_config->decoder_config.p_decoder_fifo; p_spudec->p_fifo = p_config->decoder_config.p_decoder_fifo;
...@@ -106,7 +107,8 @@ static int InitThread( spudec_thread_t *p_spudec ) ...@@ -106,7 +107,8 @@ static int InitThread( spudec_thread_t *p_spudec )
{ {
intf_DbgMsg("spudec debug: initializing spu decoder thread %p", p_spudec); intf_DbgMsg("spudec debug: initializing spu decoder thread %p", p_spudec);
p_spudec->p_config->decoder_config.pf_init_bit_stream( &p_spudec->bit_stream, p_spudec->p_config->decoder_config.pf_init_bit_stream(
&p_spudec->bit_stream,
p_spudec->p_config->decoder_config.p_decoder_fifo ); p_spudec->p_config->decoder_config.p_decoder_fifo );
/* Mark thread as running and return */ /* Mark thread as running and return */
......
...@@ -39,10 +39,8 @@ typedef struct spudec_thread_s ...@@ -39,10 +39,8 @@ typedef struct spudec_thread_s
vdec_config_t * p_config; vdec_config_t * p_config;
/* /*
* Decoder properties * Output properties
*/ */
unsigned int total_bits_read;
/* ... */
vout_thread_t * p_vout; /* needed to create the spu objects */ vout_thread_t * p_vout; /* needed to create the spu objects */
} spudec_thread_t; } spudec_thread_t;
......
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