Commit 8153d415 authored by Michel Lespinasse's avatar Michel Lespinasse

Proprification du decodeur mpeg audio, comme j'avais fait pour l'ac3 :
separation de ce qui est specifique videolan et de ce qui est generique.

Je compte encore bidouiller pas mal la partie generique, mais deja la ca
marche donc...
parent 4eed2dd0
# Generated automatically from Makefile.in by configure.
# Generated automatically from Makefile.in by configure.
################################################################################
# vlc (VideoLAN Client) main makefile
# (c)1998 VideoLAN
################################################################################
# This makefile is the main makefile for the VideoLAN client.
################################################################################
CC = egcc
################################################################################
# Configuration
################################################################################
# Audio output settings
AOUT = dsp
#AOUT += esd
# Not yet supported
#AOUT += alsa
# Fallback method that should always work
AOUT += dummy
# Video output settings
VOUT = x11
#VOUT += fb
#VOUT += ggi
#VOUT += glide
# Not yet supported
#VOUT = beos
#VOUT += dga
# Fallback method that should always work
VOUT += dummy
# Interface settings
INTF = x11
#INTF += fb
#INTF += ggi
#INTF += glide
# Not yet supported
#INTF = beos
#INTF += dga
# Fallback method that should always work
INTF += dummy
# Target architecture
ARCH=X86
#ARCH=PPC
#ARCH=SPARC
# Target operating system
SYS=LINUX
#SYS=GNU
#SYS=BSD
#SYS=BEOS
# For x86 architecture, choose MMX support
ARCH += MMX
# For x86 architecture, optimize for Pentium Pro
# (choose NO if you get `Invalid instruction' errors)
ARCH += PPRO
# Decoder choice - ?? old decoder will be removed soon
#DECODER=old
DECODER=new
# Debugging mode on or off (set to 1 to activate)
DEBUG=0
#----------------- do not change anything below this line ----------------------
################################################################################
# Configuration pre-processing
################################################################################
# PROGRAM_OPTIONS is an identification string of the compilation options
PROGRAM_OPTIONS = $(SYS) $(ARCH)
ifeq ($(DEBUG),1)
PROGRAM_OPTIONS += DEBUG
endif
# PROGRAM_BUILD is a complete identification of the build
# ( we can't use fancy options with date since OSes like Solaris
# or FreeBSD have strange date implementations )
PROGRAM_BUILD = `date` $(USER)
# XXX: beos does not support hostname
#PROGRAM_BUILD = `date` $(USER)@`hostname`
# DEFINE will contain some of the constants definitions decided in Makefile,
# including ARCH_xx and SYS_xx. It will be passed to C compiler.
DEFINE += -DARCH_$(shell echo $(ARCH) | cut -f1 -d' ')
DEFINE += -DSYS_$(SYS)
DEFINE += -DPLUGIN_PATH="\"$(PREFIX)/lib/videolan/vlc\""
DEFINE += -DPROGRAM_VERSION="\"0.1.99\""
DEFINE += -DPROGRAM_CODENAME="\"Onatopp\""
#DEFINE += -DPROGRAM_OPTIONS="\"$(shell echo $(PROGRAM_OPTIONS) | tr 'A-Z' 'a-z')\""
#DEFINE += -DPROGRAM_BUILD="\"$(PROGRAM_BUILD)\""
ifeq ($(DEBUG),1)
DEFINE += -DDEBUG
endif
################################################################################
# Tuning and other variables - do not change anything except if you know
# exactly what you are doing
################################################################################
#
# C headers directories
#
INCLUDE += -Iinclude -I/usr/local/include -I/usr/X11R6/include
#
# Libraries
#
ifeq ($(SYS),GNU)
LIB += -lthreads -ldl
endif
ifeq ($(SYS),BSD)
LIB += -pthread -lgnugetopt
LIB += -L/usr/local/lib
endif
ifeq ($(SYS),LINUX)
LIB += -lpthread -ldl
endif
ifeq ($SYS),BEOS)
LIB += -llibroot -llibgame -llibbe
endif
LIB += -lm
#
# C compiler flags: compilation
#
CCFLAGS += $(DEFINE) $(INCLUDE)
CCFLAGS += -Wall
CCFLAGS += -D_REENTRANT
CCFLAGS += -D_GNU_SOURCE
# Optimizations : don't compile debug versions with them
CCFLAGS += -O6
CCFLAGS += -ffast-math -funroll-loops -fargument-noalias-global
CCFLAGS += -fomit-frame-pointer
# Optimizations for x86 familiy
ifneq (,$(findstring X86,$(ARCH)))
CCFLAGS += -malign-double
#CCFLAGS += -march=pentium
# Eventual Pentium Pro optimizations
ifneq (,$(findstring PPRO,$(ARCH)))
ifneq ($(SYS), BSD)
CCFLAGS += -march=pentiumpro
endif
endif
# Eventual MMX optimizations for x86
ifneq (,$(findstring MMX,$(ARCH)))
CFLAGS += -DHAVE_MMX
endif
endif
# Optimizations for PowerPC
ifneq (,$(findstring PPC,$(ARCH)))
CCFLAGS += -mcpu=604e -mmultiple -mhard-float -mstring
endif
# Optimizations for Sparc
ifneq (,$(findstring SPARC,$(ARCH)))
CCFLAGS += -mhard-float
endif
#
# C compiler flags: dependancies
#
DCFLAGS += $(INCLUDE)
DCFLAGS += -MM
#
# C compiler flags: linking
#
LCFLAGS += $(LIB)
LCFLAGS += -Wall
#LCFLAGS += -s
#
# Additionnal debugging flags
#
# Debugging support
ifeq ($(DEBUG),1)
CFLAGS += -g
#CFLAGS += -pg
endif
#################################################################################
# Objects and files
#################################################################################
#
# C Objects
#
interface_obj = interface/main.o \
interface/interface.o \
interface/intf_msg.o \
interface/intf_cmd.o \
interface/intf_ctrl.o \
interface/intf_console.o
input_obj = input/input_vlan.o \
input/input_file.o \
input/input_netlist.o \
input/input_network.o \
input/input_ctrl.o \
input/input_pcr.o \
input/input_psi.o \
input/input.o
audio_output_obj = audio_output/audio_output.o
video_output_obj = video_output/video_output.o \
video_output/video_text.o \
video_output/video_yuv.o
ac3_decoder_obj = ac3_decoder/ac3_decoder_thread.o \
ac3_decoder/ac3_decoder.o \
ac3_decoder/ac3_parse.o \
ac3_decoder/ac3_exponent.o \
ac3_decoder/ac3_bit_allocate.o \
ac3_decoder/ac3_mantissa.o \
ac3_decoder/ac3_rematrix.o \
ac3_decoder/ac3_imdct.o \
ac3_decoder/ac3_downmix.o
audio_decoder_obj = audio_decoder/audio_decoder_thread.o \
audio_decoder/audio_decoder.o \
audio_decoder/audio_math.o
spu_decoder_obj = spu_decoder/spu_decoder.o
#??generic_decoder_obj = generic_decoder/generic_decoder.o
# remeber to add it to OBJ
ifeq ($(DECODER),old)
CFLAGS += -DOLD_DECODER
video_decoder_obj = video_decoder_ref/video_decoder.o \
video_decoder_ref/display.o \
video_decoder_ref/getblk.o \
video_decoder_ref/gethdr.o \
video_decoder_ref/getpic.o \
video_decoder_ref/getvlc.o \
video_decoder_ref/idct.o \
video_decoder_ref/motion.o \
video_decoder_ref/mpeg2dec.o \
video_decoder_ref/recon.o \
video_decoder_ref/spatscal.o
else
video_parser_obj = video_parser/video_parser.o \
video_parser/vpar_headers.o \
video_parser/vpar_blocks.o \
video_parser/vpar_synchro.o \
video_parser/video_fifo.o
video_decoder_obj = video_decoder/video_decoder.o \
video_decoder/vdec_motion.o \
video_decoder/vdec_motion_inner.o \
video_decoder/vdec_idct.o
endif
misc_obj = misc/mtime.o \
misc/rsc_files.o \
misc/netutils.o \
misc/plugins.o \
misc/decoder_fifo.o
C_OBJ = $(interface_obj) \
$(input_obj) \
$(audio_output_obj) \
$(video_output_obj) \
$(ac3_decoder_obj) \
$(audio_decoder_obj) \
$(spu_decoder_obj) \
$(generic_decoder_obj) \
$(video_parser_obj) \
$(video_decoder_obj) \
$(vlan_obj) \
$(misc_obj)
#
# Assembler Objects
#
ifneq (,$(findstring X86,$(ARCH)))
ifneq (,$(findstring MMX,$(ARCH)))
ifeq ($(DECODER),new)
ASM_OBJ = video_decoder/vdec_idctmmx.o \
video_output/video_yuv_mmx.o
else
ASM_OBJ = video_decoder_ref/vdec_idctmmx.o \
video_output/video_yuv_mmx.o
endif
endif
endif
#
# Plugins
#
intf_plugin = $(INTF:%=plugins/intf/intf_%.so)
aout_plugin = $(AOUT:%=plugins/aout/aout_%.so)
vout_plugin = $(VOUT:%=plugins/vout/vout_%.so)
PLUGIN_OBJ = $(intf_plugin) $(aout_plugin) $(vout_plugin)
#
# Other lists of files
#
C_OBJ := $(C_OBJ:%.o=src/%.o)
ASM_OBJ := $(ASM_OBJ:%.o=src/%.o)
sources := $(C_OBJ:%.o=%.c) $(PLUGIN_OBJ:%.so=%.c)
dependancies := $(sources:%.c=.dep/%.d)
# All symbols must be exported
export
################################################################################
# Targets
################################################################################
#
# Virtual targets
#
all: vlc
clean:
rm -f $(C_OBJ) $(ASM_OBJ) $(PLUGIN_OBJ)
distclean: clean
rm -f **/*.o **/*.so **/*~ *.log
rm -f Makefile include/defs.h config.cache config.log
rm -f vlc gmon.out core
rm -rf .dep
install:
$(INSTALL) vlc $(PREFIX)/bin
mkdir -p $(PREFIX)/lib/videolan/vlc
$(INSTALL) $(PLUGIN_OBJ) $(PREFIX)/lib/videolan/vlc
show:
@echo "Command line for C objects:"
@echo $(CC) $(CCFLAGS) $(CFLAGS) -c -o "<dest.o>" "<src.c>"
@echo
@echo "Command line for assembler objects:"
@echo $(CC) $(CFLAGS) -c -o "<dest.o>" "<src.S>"
FORCE:
#
# Real targets
#
vlc: $(C_OBJ) $(ASM_OBJ) $(PLUGIN_OBJ)
$(CC) $(CCFLAGS) $(LCFLAGS) $(CFLAGS) --export-dynamic -rdynamic -o $@ $(C_OBJ) $(ASM_OBJ)
#
# Generic rules (see below)
#
$(dependancies): %.d: FORCE
@$(MAKE) -s --no-print-directory -f Makefile.dep $@
$(C_OBJ): %.o: Makefile.dep
$(C_OBJ): %.o: .dep/%.d
$(C_OBJ): %.o: %.c
@echo "compiling $*.o from $*.c"
@$(CC) $(CCFLAGS) $(CFLAGS) -c -o $@ $<
$(ASM_OBJ): %.o: Makefile.dep
$(ASM_OBJ): %.o: %.S
@echo "assembling $*.o from $*.S"
@$(CC) $(CFLAGS) -c -o $@ $<
$(PLUGIN_OBJ): %.so: Makefile.dep
$(PLUGIN_OBJ): %.so: .dep/%.d
# audio plugins
plugins/aout/aout_dummy.so plugins/aout/aout_dsp.so: %.so: %.c
@echo "compiling $*.so from $*.c"
ifeq ($(SYS), BEOS)
@$(CC) $(CCFLAGS) $(CFLAGS) -nostart -o $@ $<
else
@$(CC) $(CCFLAGS) $(CFLAGS) -shared -o $@ $<
endif
plugins/aout/aout_esd.so: %.so: %.c
@echo "compiling $*.so from $*.c"
ifeq ($(SYS), BSD)
@$(CC) $(CCFLAGS) $(CFLAGS) -lesd -shared -o $@ $<
else
@$(CC) $(CCFLAGS) $(CFLAGS) -laudiofile -lesd -shared -o $@ $<
endif
# video plugins
plugins/intf/intf_dummy.so plugins/vout/vout_dummy.so \
plugins/intf/intf_fb.so plugins/vout/vout_fb.so: %.so: %.c
@echo "compiling $*.so from $*.c"
ifeq ($(SYS), BEOS)
@$(CC) $(CCFLAGS) $(CFLAGS) -nostart -o $@ $<
else
@$(CC) $(CCFLAGS) $(CFLAGS) -shared -o $@ $<
endif
plugins/intf/intf_x11.so plugins/vout/vout_x11.so: %.so: %.c
@echo "compiling $*.so from $*.c"
@$(CC) $(CCFLAGS) $(CFLAGS) -I/usr/X11R6/include -L/usr/X11R6/lib -lX11 -lXext -shared -o $@ $<
plugins/intf/intf_glide.so plugins/vout/vout_glide.so: %.so: %.c
@echo "compiling $*.so from $*.c"
@$(CC) $(CCFLAGS) $(CFLAGS) -I/usr/include/glide -lglide2x -shared -o $@ $<
plugins/intf/intf_ggi.so plugins/vout/vout_ggi.so: %.so: %.c
@echo "compiling $*.so from $*.c"
@$(CC) $(CCFLAGS) $(CFLAGS) -lggi -shared -o $@ $<
################################################################################
# Note on generic rules and dependancies
################################################################################
# Note on dependancies: each .c file is associated with a .d file, which
# depends of it. The .o file associated with a .c file depends of the .d, of the
# .c itself, and of Makefile. The .d files are stored in a separate .dep/
# directory.
# The dep directory should be ignored by CVS.
# Note on inclusions: depending of the target, the dependancies files must
# or must not be included. The problem is that if we ask make to include a file,
# and this file does not exist, it is made before it can be included. In a
# general way, a .d file should be included if and only if the corresponding .o
# needs to be re-made.
# Two makefiles are used: the main one (this one) has regular generic rules,
# except for .o files, for which it calls the object Makefile. Dependancies
# are not included in this file.
# The object Makefile known how to make a .o from a .c, and includes
# dependancies for the target, but only those required.
...@@ -230,7 +230,8 @@ ac3_decoder_obj = ac3_decoder/ac3_decoder_thread.o \ ...@@ -230,7 +230,8 @@ ac3_decoder_obj = ac3_decoder/ac3_decoder_thread.o \
ac3_decoder/ac3_imdct.o \ ac3_decoder/ac3_imdct.o \
ac3_decoder/ac3_downmix.o ac3_decoder/ac3_downmix.o
audio_decoder_obj = audio_decoder/audio_decoder.o \ audio_decoder_obj = audio_decoder/audio_decoder_thread.o \
audio_decoder/audio_decoder.o \
audio_decoder/audio_math.o audio_decoder/audio_math.o
spu_decoder_obj = spu_decoder/spu_decoder.o spu_decoder_obj = spu_decoder/spu_decoder.o
......
/***************************************************************************** /*****************************************************************************
* audio_decoder.h : audio decoder thread interface * audio_decoder.h : audio decoder interface
***************************************************************************** *****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN * Copyright (C) 1999, 2000 VideoLAN
* *
...@@ -21,87 +21,71 @@ ...@@ -21,87 +21,71 @@
* Boston, MA 02111-1307, USA. * Boston, MA 02111-1307, USA.
*****************************************************************************/ *****************************************************************************/
/***************************************************************************** /**** audio decoder API - public audio decoder structures */
* = Prototyped functions are implemented in audio_decoder/audio_decoder.c
*
* = Required headers :
* - "common.h" ( u32, byte_t, boolean_t )
* - "threads.h" ( vlc_thread_t )
* - "input.h" ( ts_packet_t, input_thread_t )
* - "decoder_fifo.h" ( decoder_fifo_t )
* - "audio_output.h" ( aout_fifo_t, aout_thread_t )
*
* = - LSb = Least Significant bit
* - LSB = Least Significant Byte
*
* = - MSb = Most Significant bit
* - MSB = Most Significant Byte
*****************************************************************************/
/* typedef struct audiodec_s audiodec_t;
* TODO :
* - Etudier /usr/include/asm/bitops.h d'un peu plus prs, bien qu'il ne me
* semble pas tre possible d'utiliser ces fonctions ici
* - N'y aurait-t-il pas moyen de se passer d'un buffer de bits, en travaillant
* directement sur le flux PES ?
*/
#define ADEC_FRAME_SIZE 384 typedef struct adec_sync_info_s {
int sample_rate; /* sample rate in Hz */
int frame_size; /* frame size in bytes */
int bit_rate; /* nominal bit rate in kbps */
} adec_sync_info_t;
/***************************************************************************** typedef struct adec_byte_stream_s {
* adec_frame_t u8 * p_byte;
*****************************************************************************/ u8 * p_end;
typedef s16 adec_frame_t[ ADEC_FRAME_SIZE ]; void * info;
} adec_byte_stream_t;
/***************************************************************************** /**** audio decoder API - functions publically provided by the audio dec. ****/
* adec_bank_t
*****************************************************************************/ int adec_init (audiodec_t * p_adec);
typedef struct adec_bank_s 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 {
* adec_thread_t : audio decoder thread descriptor u32 buffer;
***************************************************************************** int i_available;
* This type describes an audio decoder thread adec_byte_stream_t byte_stream;
*****************************************************************************/ int total_bytes_read;
typedef struct adec_thread_s } adec_bit_stream_t;
{
/*
* Thread properties
*/
vlc_thread_t thread_id; /* id for thread functions */
boolean_t b_die; /* `die' flag */
boolean_t b_error; /* `error' flag */
struct audiodec_s {
/* /*
* Input properties * Input properties
*/ */
decoder_fifo_t fifo; /* stores the PES stream data */
/* The bit stream structure handles the PES stream at the bit level */ /* The bit stream structure handles the PES stream at the bit level */
bit_stream_t bit_stream; adec_bit_stream_t bit_stream;
/* /*
* Decoder properties * Decoder properties
*/ */
u32 header;
int frame_size;
adec_bank_t bank_0; adec_bank_t bank_0;
adec_bank_t bank_1; adec_bank_t bank_1;
};
/* /**** audio decoder inline functions ****/
* Output properties
*/
aout_fifo_t * p_aout_fifo; /* stores the decompressed audio frames */
aout_thread_t * p_aout; /* needed to create the audio fifo */
} adec_thread_t;
/***************************************************************************** static adec_byte_stream_t * adec_byte_stream (audiodec_t * p_adec)
* Prototypes {
*****************************************************************************/ return &(p_adec->bit_stream.byte_stream);
adec_thread_t * adec_CreateThread ( input_thread_t * p_input /* !! , aout_thread_t * p_aout !! */ ); }
void adec_DestroyThread ( adec_thread_t * p_adec );
/*****************************************************************************
* audio_decoder_thread.h : audio decoder thread interface
*****************************************************************************
* Copyright (C) 1999, 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-1307, USA.
*****************************************************************************/
/*****************************************************************************
* adec_thread_t : audio decoder thread descriptor
*****************************************************************************/
typedef struct adec_thread_s
{
/*
* Thread properties
*/
vlc_thread_t thread_id; /* id for thread functions */
boolean_t b_die; /* `die' flag */
boolean_t b_error; /* `error' flag */
/*
* Input properties
*/
decoder_fifo_t fifo; /* stores the PES stream data */
input_thread_t * p_input;
ts_packet_t * p_ts;
int align;
/*
* Decoder properties
*/
audiodec_t audio_decoder;
/*
* Output properties
*/
aout_fifo_t * p_aout_fifo; /* stores the decompressed audio frames */
aout_thread_t * p_aout; /* needed to create the audio fifo */
} adec_thread_t;
/*****************************************************************************
* Prototypes
*****************************************************************************/
adec_thread_t * adec_CreateThread ( input_thread_t * p_input /* !! , aout_thread_t * p_aout !! */ );
void adec_DestroyThread ( adec_thread_t * p_adec );
...@@ -61,30 +61,28 @@ ...@@ -61,30 +61,28 @@
#include "ac3_decoder_thread.h" #include "ac3_decoder_thread.h"
#define AC3DEC_FRAME_SIZE (2*1536) #define AC3DEC_FRAME_SIZE (2*1536)
typedef s16 ac3dec_frame_t[ AC3DEC_FRAME_SIZE ];
/***************************************************************************** /*****************************************************************************
* Local prototypes * Local prototypes
*****************************************************************************/ *****************************************************************************/
static int InitThread ( ac3dec_thread_t * p_adec ); static int InitThread (ac3dec_thread_t * p_adec);
static void RunThread ( ac3dec_thread_t * p_adec ); static void RunThread (ac3dec_thread_t * p_adec);
static void ErrorThread ( ac3dec_thread_t * p_adec ); static void ErrorThread (ac3dec_thread_t * p_adec);
static void EndThread ( ac3dec_thread_t * p_adec ); static void EndThread (ac3dec_thread_t * p_adec);
/***************************************************************************** /*****************************************************************************
* ac3dec_CreateThread: creates an ac3 decoder thread * ac3dec_CreateThread: creates an ac3 decoder thread
*****************************************************************************/ *****************************************************************************/
ac3dec_thread_t * ac3dec_CreateThread( input_thread_t * p_input ) ac3dec_thread_t * ac3dec_CreateThread (input_thread_t * p_input)
{ {
ac3dec_thread_t * p_ac3dec; ac3dec_thread_t * p_ac3dec;
intf_DbgMsg("ac3dec debug: creating ac3 decoder thread\n"); intf_DbgMsg ("ac3dec debug: creating ac3 decoder thread\n");
/* Allocate the memory needed to store the thread's structure */ /* Allocate the memory needed to store the thread's structure */
if ( (p_ac3dec = (ac3dec_thread_t *)malloc( sizeof(ac3dec_thread_t) )) == NULL ) if ((p_ac3dec = (ac3dec_thread_t *)malloc (sizeof(ac3dec_thread_t))) == NULL) {
{ intf_ErrMsg ("ac3dec error: not enough memory for ac3dec_CreateThread() to create the new thread\n");
intf_ErrMsg("ac3dec error: not enough memory for ac3dec_CreateThread() to create the new thread\n"); return NULL;
return( NULL );
} }
/* /*
...@@ -98,8 +96,8 @@ ac3dec_thread_t * ac3dec_CreateThread( input_thread_t * p_input ) ...@@ -98,8 +96,8 @@ ac3dec_thread_t * ac3dec_CreateThread( input_thread_t * p_input )
*/ */
/* Initialize the decoder fifo's data lock and conditional variable and set /* Initialize the decoder fifo's data lock and conditional variable and set
* its buffer as empty */ * its buffer as empty */
vlc_mutex_init( &p_ac3dec->fifo.data_lock ); vlc_mutex_init (&p_ac3dec->fifo.data_lock);
vlc_cond_init( &p_ac3dec->fifo.data_wait ); vlc_cond_init (&p_ac3dec->fifo.data_wait);
p_ac3dec->fifo.i_start = 0; p_ac3dec->fifo.i_start = 0;
p_ac3dec->fifo.i_end = 0; p_ac3dec->fifo.i_end = 0;
...@@ -116,35 +114,34 @@ ac3dec_thread_t * ac3dec_CreateThread( input_thread_t * p_input ) ...@@ -116,35 +114,34 @@ ac3dec_thread_t * ac3dec_CreateThread( input_thread_t * p_input )
p_ac3dec->p_aout_fifo = NULL; p_ac3dec->p_aout_fifo = NULL;
/* Spawn the ac3 decoder thread */ /* Spawn the ac3 decoder thread */
if ( vlc_thread_create(&p_ac3dec->thread_id, "ac3 decoder", (vlc_thread_func_t)RunThread, (void *)p_ac3dec) ) if (vlc_thread_create(&p_ac3dec->thread_id, "ac3 decoder", (vlc_thread_func_t)RunThread, (void *)p_ac3dec)) {
{ intf_ErrMsg ("ac3dec error: can't spawn ac3 decoder thread\n");
intf_ErrMsg( "ac3dec error: can't spawn ac3 decoder thread\n" ); free (p_ac3dec);
free( p_ac3dec ); return NULL;
return( NULL );
} }
intf_DbgMsg( "ac3dec debug: ac3 decoder thread (%p) created\n", p_ac3dec ); intf_DbgMsg ("ac3dec debug: ac3 decoder thread (%p) created\n", p_ac3dec);
return( p_ac3dec ); return p_ac3dec;
} }
/***************************************************************************** /*****************************************************************************
* ac3dec_DestroyThread: destroys an ac3 decoder thread * ac3dec_DestroyThread: destroys an ac3 decoder thread
*****************************************************************************/ *****************************************************************************/
void ac3dec_DestroyThread( ac3dec_thread_t * p_ac3dec ) void ac3dec_DestroyThread (ac3dec_thread_t * p_ac3dec)
{ {
intf_DbgMsg( "ac3dec debug: requesting termination of ac3 decoder thread %p\n", p_ac3dec ); intf_DbgMsg ("ac3dec debug: requesting termination of ac3 decoder thread %p\n", p_ac3dec);
/* Ask thread to kill itself */ /* Ask thread to kill itself */
p_ac3dec->b_die = 1; p_ac3dec->b_die = 1;
/* Make sure the decoder thread leaves the GetByte() function */ /* Make sure the decoder thread leaves the GetByte() function */
vlc_mutex_lock( &(p_ac3dec->fifo.data_lock) ); vlc_mutex_lock (&(p_ac3dec->fifo.data_lock));
vlc_cond_signal( &(p_ac3dec->fifo.data_wait) ); vlc_cond_signal (&(p_ac3dec->fifo.data_wait));
vlc_mutex_unlock( &(p_ac3dec->fifo.data_lock) ); vlc_mutex_unlock (&(p_ac3dec->fifo.data_lock));
/* Waiting for the decoder thread to exit */ /* Waiting for the decoder thread to exit */
/* Remove this as soon as the "status" flag is implemented */ /* Remove this as soon as the "status" flag is implemented */
vlc_thread_join( p_ac3dec->thread_id ); vlc_thread_join (p_ac3dec->thread_id);
} }
/* Following functions are local */ /* Following functions are local */
...@@ -152,33 +149,31 @@ void ac3dec_DestroyThread( ac3dec_thread_t * p_ac3dec ) ...@@ -152,33 +149,31 @@ void ac3dec_DestroyThread( ac3dec_thread_t * p_ac3dec )
/***************************************************************************** /*****************************************************************************
* InitThread : initialize an ac3 decoder thread * InitThread : initialize an ac3 decoder thread
*****************************************************************************/ *****************************************************************************/
static int InitThread( ac3dec_thread_t * p_ac3dec ) static int InitThread (ac3dec_thread_t * p_ac3dec)
{ {
aout_fifo_t aout_fifo; aout_fifo_t aout_fifo;
ac3_byte_stream_t * byte_stream; ac3_byte_stream_t * byte_stream;
intf_DbgMsg( "ac3dec debug: initializing ac3 decoder thread %p\n", p_ac3dec ); intf_DbgMsg ("ac3dec debug: initializing ac3 decoder thread %p\n", p_ac3dec);
/* Our first job is to initialize the bit stream structure with the /* Our first job is to initialize the bit stream structure with the
* beginning of the input stream */ * beginning of the input stream */
vlc_mutex_lock( &p_ac3dec->fifo.data_lock ); vlc_mutex_lock (&p_ac3dec->fifo.data_lock);
while ( DECODER_FIFO_ISEMPTY(p_ac3dec->fifo) ) while (DECODER_FIFO_ISEMPTY(p_ac3dec->fifo)) {
{ if (p_ac3dec->b_die) {
if ( p_ac3dec->b_die ) vlc_mutex_unlock (&p_ac3dec->fifo.data_lock);
{ return -1;
vlc_mutex_unlock( &p_ac3dec->fifo.data_lock );
return( -1 );
} }
vlc_cond_wait( &p_ac3dec->fifo.data_wait, &p_ac3dec->fifo.data_lock ); vlc_cond_wait (&p_ac3dec->fifo.data_wait, &p_ac3dec->fifo.data_lock);
} }
p_ac3dec->p_ts = DECODER_FIFO_START( p_ac3dec->fifo )->p_first_ts; p_ac3dec->p_ts = DECODER_FIFO_START (p_ac3dec->fifo)->p_first_ts;
byte_stream = ac3_byte_stream (&p_ac3dec->ac3_decoder); byte_stream = ac3_byte_stream (&p_ac3dec->ac3_decoder);
byte_stream->p_byte = byte_stream->p_byte =
p_ac3dec->p_ts->buffer + p_ac3dec->p_ts->i_payload_start; p_ac3dec->p_ts->buffer + p_ac3dec->p_ts->i_payload_start;
byte_stream->p_end = byte_stream->p_end =
p_ac3dec->p_ts->buffer + p_ac3dec->p_ts->i_payload_end; p_ac3dec->p_ts->buffer + p_ac3dec->p_ts->i_payload_end;
byte_stream->info = p_ac3dec; byte_stream->info = p_ac3dec;
vlc_mutex_unlock( &p_ac3dec->fifo.data_lock ); vlc_mutex_unlock (&p_ac3dec->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;
...@@ -187,29 +182,27 @@ static int InitThread( ac3dec_thread_t * p_ac3dec ) ...@@ -187,29 +182,27 @@ static int InitThread( ac3dec_thread_t * p_ac3dec )
aout_fifo.l_frame_size = AC3DEC_FRAME_SIZE; aout_fifo.l_frame_size = AC3DEC_FRAME_SIZE;
/* Creating the audio output fifo */ /* Creating the audio output fifo */
if ( (p_ac3dec->p_aout_fifo = aout_CreateFifo(p_ac3dec->p_aout, &aout_fifo)) == NULL ) if ((p_ac3dec->p_aout_fifo = aout_CreateFifo(p_ac3dec->p_aout, &aout_fifo)) == NULL) {
{ return -1;
return( -1 );
} }
intf_DbgMsg( "ac3dec debug: ac3 decoder thread %p initialized\n", p_ac3dec ); intf_DbgMsg ("ac3dec debug: ac3 decoder thread %p initialized\n", p_ac3dec);
return( 0 ); return 0;
} }
/***************************************************************************** /*****************************************************************************
* RunThread : ac3 decoder thread * RunThread : ac3 decoder thread
*****************************************************************************/ *****************************************************************************/
static void RunThread( ac3dec_thread_t * p_ac3dec ) static void RunThread (ac3dec_thread_t * p_ac3dec)
{ {
int sync; int sync;
intf_DbgMsg( "ac3dec debug: running ac3 decoder thread (%p) (pid == %i)\n", p_ac3dec, getpid() ); intf_DbgMsg ("ac3dec debug: running ac3 decoder thread (%p) (pid == %i)\n", p_ac3dec, getpid());
msleep( INPUT_PTS_DELAY ); msleep (INPUT_PTS_DELAY);
/* Initializing the ac3 decoder thread */ /* Initializing the ac3 decoder thread */
if ( InitThread(p_ac3dec) ) /* XXX?? */ if (InitThread (p_ac3dec)) /* XXX?? */ {
{
p_ac3dec->b_error = 1; p_ac3dec->b_error = 1;
} }
...@@ -218,8 +211,7 @@ static void RunThread( ac3dec_thread_t * p_ac3dec ) ...@@ -218,8 +211,7 @@ static void RunThread( ac3dec_thread_t * p_ac3dec )
/* ac3 decoder thread's main loop */ /* ac3 decoder thread's main loop */
/* FIXME : do we have enough room to store the decoded frames ?? */ /* FIXME : do we have enough room to store the decoded frames ?? */
while ( (!p_ac3dec->b_die) && (!p_ac3dec->b_error) ) while ((!p_ac3dec->b_die) && (!p_ac3dec->b_error)) {
{
s16 * buffer; s16 * buffer;
ac3_sync_info_t sync_info; ac3_sync_info_t sync_info;
...@@ -253,13 +245,10 @@ static void RunThread( ac3dec_thread_t * p_ac3dec ) ...@@ -253,13 +245,10 @@ static void RunThread( ac3dec_thread_t * p_ac3dec )
p_ac3dec->sync_ptr = 0; p_ac3dec->sync_ptr = 0;
} }
if ( DECODER_FIFO_START(p_ac3dec->fifo)->b_has_pts ) if (DECODER_FIFO_START(p_ac3dec->fifo)->b_has_pts) {
{
p_ac3dec->p_aout_fifo->date[p_ac3dec->p_aout_fifo->l_end_frame] = DECODER_FIFO_START(p_ac3dec->fifo)->i_pts; p_ac3dec->p_aout_fifo->date[p_ac3dec->p_aout_fifo->l_end_frame] = DECODER_FIFO_START(p_ac3dec->fifo)->i_pts;
DECODER_FIFO_START(p_ac3dec->fifo)->b_has_pts = 0; DECODER_FIFO_START(p_ac3dec->fifo)->b_has_pts = 0;
} } else {
else
{
p_ac3dec->p_aout_fifo->date[p_ac3dec->p_aout_fifo->l_end_frame] = LAST_MDATE; p_ac3dec->p_aout_fifo->date[p_ac3dec->p_aout_fifo->l_end_frame] = LAST_MDATE;
} }
...@@ -270,80 +259,76 @@ static void RunThread( ac3dec_thread_t * p_ac3dec ) ...@@ -270,80 +259,76 @@ static void RunThread( ac3dec_thread_t * p_ac3dec )
p_ac3dec->p_aout_fifo->l_rate = sync_info.sample_rate; p_ac3dec->p_aout_fifo->l_rate = sync_info.sample_rate;
buffer = ((ac3dec_frame_t *)p_ac3dec->p_aout_fifo->buffer)[ p_ac3dec->p_aout_fifo->l_end_frame ]; buffer = ((s16 *)p_ac3dec->p_aout_fifo->buffer) + (p_ac3dec->p_aout_fifo->l_end_frame * AC3DEC_FRAME_SIZE);
if (ac3_decode_frame (&p_ac3dec->ac3_decoder, buffer)) { if (ac3_decode_frame (&p_ac3dec->ac3_decoder, buffer)) {
sync = 0; sync = 0;
goto bad_frame; goto bad_frame;
} }
vlc_mutex_lock( &p_ac3dec->p_aout_fifo->data_lock ); vlc_mutex_lock (&p_ac3dec->p_aout_fifo->data_lock);
p_ac3dec->p_aout_fifo->l_end_frame = (p_ac3dec->p_aout_fifo->l_end_frame + 1) & AOUT_FIFO_SIZE; p_ac3dec->p_aout_fifo->l_end_frame = (p_ac3dec->p_aout_fifo->l_end_frame + 1) & AOUT_FIFO_SIZE;
vlc_cond_signal( &p_ac3dec->p_aout_fifo->data_wait ); vlc_cond_signal (&p_ac3dec->p_aout_fifo->data_wait);
vlc_mutex_unlock( &p_ac3dec->p_aout_fifo->data_lock ); vlc_mutex_unlock (&p_ac3dec->p_aout_fifo->data_lock);
bad_frame: bad_frame:
} }
/* If b_error is set, the ac3 decoder thread enters the error loop */ /* If b_error is set, the ac3 decoder thread enters the error loop */
if ( p_ac3dec->b_error ) if (p_ac3dec->b_error) {
{ ErrorThread (p_ac3dec);
ErrorThread( p_ac3dec );
} }
/* End of the ac3 decoder thread */ /* End of the ac3 decoder thread */
EndThread( p_ac3dec ); EndThread (p_ac3dec);
} }
/***************************************************************************** /*****************************************************************************
* ErrorThread : ac3 decoder's RunThread() error loop * ErrorThread : ac3 decoder's RunThread() error loop
*****************************************************************************/ *****************************************************************************/
static void ErrorThread( ac3dec_thread_t * p_ac3dec ) static void ErrorThread (ac3dec_thread_t * p_ac3dec)
{ {
/* We take the lock, because we are going to read/write the start/end /* We take the lock, because we are going to read/write the start/end
* indexes of the decoder fifo */ * indexes of the decoder fifo */
vlc_mutex_lock( &p_ac3dec->fifo.data_lock ); vlc_mutex_lock (&p_ac3dec->fifo.data_lock);
/* Wait until a `die' order is sent */ /* Wait until a `die' order is sent */
while( !p_ac3dec->b_die ) while (!p_ac3dec->b_die) {
{
/* Trash all received PES packets */ /* Trash all received PES packets */
while( !DECODER_FIFO_ISEMPTY(p_ac3dec->fifo) ) while (!DECODER_FIFO_ISEMPTY(p_ac3dec->fifo)) {
{ input_NetlistFreePES (p_ac3dec->p_input, DECODER_FIFO_START(p_ac3dec->fifo));
input_NetlistFreePES( p_ac3dec->p_input, DECODER_FIFO_START(p_ac3dec->fifo) ); DECODER_FIFO_INCSTART (p_ac3dec->fifo);
DECODER_FIFO_INCSTART( p_ac3dec->fifo );
} }
/* Waiting for the input thread to put new PES packets in the fifo */ /* Waiting for the input thread to put new PES packets in the fifo */
vlc_cond_wait( &p_ac3dec->fifo.data_wait, &p_ac3dec->fifo.data_lock ); vlc_cond_wait (&p_ac3dec->fifo.data_wait, &p_ac3dec->fifo.data_lock);
} }
/* We can release the lock before leaving */ /* We can release the lock before leaving */
vlc_mutex_unlock( &p_ac3dec->fifo.data_lock ); vlc_mutex_unlock (&p_ac3dec->fifo.data_lock);
} }
/***************************************************************************** /*****************************************************************************
* EndThread : ac3 decoder thread destruction * EndThread : ac3 decoder thread destruction
*****************************************************************************/ *****************************************************************************/
static void EndThread( ac3dec_thread_t * p_ac3dec ) static void EndThread (ac3dec_thread_t * p_ac3dec)
{ {
intf_DbgMsg( "ac3dec debug: destroying ac3 decoder thread %p\n", p_ac3dec ); intf_DbgMsg ("ac3dec debug: destroying ac3 decoder thread %p\n", p_ac3dec);
/* If the audio output fifo was created, we destroy it */ /* If the audio output fifo was created, we destroy it */
if ( p_ac3dec->p_aout_fifo != NULL ) if (p_ac3dec->p_aout_fifo != NULL) {
{ aout_DestroyFifo (p_ac3dec->p_aout_fifo);
aout_DestroyFifo( p_ac3dec->p_aout_fifo );
/* Make sure the output thread leaves the NextFrame() function */ /* Make sure the output thread leaves the NextFrame() function */
vlc_mutex_lock( &(p_ac3dec->p_aout_fifo->data_lock) ); vlc_mutex_lock (&(p_ac3dec->p_aout_fifo->data_lock));
vlc_cond_signal( &(p_ac3dec->p_aout_fifo->data_wait) ); vlc_cond_signal (&(p_ac3dec->p_aout_fifo->data_wait));
vlc_mutex_unlock( &(p_ac3dec->p_aout_fifo->data_lock) ); vlc_mutex_unlock (&(p_ac3dec->p_aout_fifo->data_lock));
} }
/* Destroy descriptor */ /* Destroy descriptor */
free( p_ac3dec ); free (p_ac3dec);
intf_DbgMsg( "ac3dec debug: ac3 decoder thread %p destroyed\n", p_ac3dec ); intf_DbgMsg ("ac3dec debug: ac3 decoder thread %p destroyed\n", p_ac3dec);
} }
void ac3_byte_stream_next (ac3_byte_stream_t * p_byte_stream) void ac3_byte_stream_next (ac3_byte_stream_t * p_byte_stream)
...@@ -374,12 +359,12 @@ void ac3_byte_stream_next (ac3_byte_stream_t * p_byte_stream) ...@@ -374,12 +359,12 @@ void ac3_byte_stream_next (ac3_byte_stream_t * p_byte_stream)
* pointer to the current PES packet, and we weren't able to * 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 * give it back to the netlist. That's why we free the PES
* packet first. */ * packet first. */
input_NetlistFreePES (p_ac3dec->p_input, DECODER_FIFO_START(p_ac3dec->fifo) ); input_NetlistFreePES (p_ac3dec->p_input, DECODER_FIFO_START(p_ac3dec->fifo));
DECODER_FIFO_INCSTART (p_ac3dec->fifo); DECODER_FIFO_INCSTART (p_ac3dec->fifo);
while (DECODER_FIFO_ISEMPTY(p_ac3dec->fifo)) { while (DECODER_FIFO_ISEMPTY(p_ac3dec->fifo)) {
vlc_cond_wait (&p_ac3dec->fifo.data_wait, &p_ac3dec->fifo.data_lock ); vlc_cond_wait (&p_ac3dec->fifo.data_wait, &p_ac3dec->fifo.data_lock);
if (p_ac3dec->p_input->b_die) { if (p_ac3dec->p_input->b_die) {
vlc_mutex_unlock (&(p_ac3dec->fifo.data_lock)); vlc_mutex_unlock (&(p_ac3dec->fifo.data_lock));
......
/*****************************************************************************
* 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-1307, 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;
}
/***************************************************************************** /*****************************************************************************
* audio_decoder.c: MPEG1 Layer I-II audio decoder thread * audio_decoder.c: MPEG1 Layer I-II audio decoder
***************************************************************************** *****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN * Copyright (C) 1999, 2000 VideoLAN
* *
...@@ -25,176 +25,16 @@ ...@@ -25,176 +25,16 @@
* TODO : * 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() ;
* *
*/ */
/***************************************************************************** #include "int_types.h"
* Preamble
*****************************************************************************/
#include "defs.h"
#include <unistd.h> /* getpid() */
#include <stdio.h> /* "intf_msg.h" */
#include <stdlib.h> /* malloc(), free() */
#include <sys/types.h> /* on BSD, uio.h needs types.h */
#include <sys/uio.h> /* "input.h" */
#include "config.h"
#include "common.h"
#include "threads.h"
#include "mtime.h"
#include "plugins.h"
#include "debug.h" /* "input_netlist.h" */
#include "intf_msg.h" /* intf_DbgMsg(), intf_ErrMsg() */
#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_constants.h" #include "audio_constants.h"
#include "audio_decoder.h" #include "audio_decoder.h"
#include "audio_math.h" /* DCT32(), PCM() */ #include "audio_math.h" /* DCT32(), PCM() */
#include "audio_bit_stream.h"
/***************************************************************************** #define NULL ((void *)0)
* 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 );
/*
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 );
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 );
*/
/*****************************************************************************
* 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 )
{
adec_thread_t * p_adec;
intf_DbgMsg("adec debug: creating audio decoder thread\n");
/* Allocate the memory needed to store the thread's structure */
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 );
}
/*
* 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 */
vlc_mutex_init( &p_adec->fifo.data_lock );
vlc_cond_init( &p_adec->fifo.data_wait );
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;
/*
* 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;
/*
* Initialize the output properties
*/
p_adec->p_aout = p_input->p_aout;
p_adec->p_aout_fifo = NULL;
/* Spawn the audio decoder thread */
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\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;
/* Make sure the decoder thread leaves the GetByte() function */
vlc_mutex_lock( &(p_adec->fifo.data_lock) );
vlc_cond_signal( &(p_adec->fifo.data_wait) );
vlc_mutex_unlock( &(p_adec->fifo.data_lock) );
/* Waiting for the decoder thread to exit */
/* Remove this as soon as the "status" flag is implemented */
vlc_thread_join( p_adec->thread_id );
}
/* Following functions are local */
/*****************************************************************************
* 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) )
{
NeedBits( &p_adec->bit_stream, 32 );
if ( (p_adec->bit_stream.fifo.buffer & ADEC_HEADER_SYNCWORD_MASK) == ADEC_HEADER_SYNCWORD_MASK )
{
return( 0 );
}
DumpBits( &p_adec->bit_stream, 8 );
}
return( -1 );
}
/***************************************************************************** /*****************************************************************************
* adec_Layer`L'_`M': decodes an mpeg 1, layer `L', mode `M', audio frame * adec_Layer`L'_`M': decodes an mpeg 1, layer `L', mode `M', audio frame
...@@ -208,41 +48,41 @@ static int FindHeader( adec_thread_t * p_adec ) ...@@ -208,41 +48,41 @@ static int FindHeader( adec_thread_t * p_adec )
/***************************************************************************** /*****************************************************************************
* adec_Layer1_Mono * adec_Layer1_Mono
*****************************************************************************/ *****************************************************************************/
static __inline__ int adec_Layer1_Mono( adec_thread_t * p_adec ) static __inline__ int adec_Layer1_Mono (audiodec_t * p_adec)
{ {
p_adec->bit_stream.fifo.buffer = 0; p_adec->bit_stream.buffer = 0;
p_adec->bit_stream.fifo.i_available = 0; p_adec->bit_stream.i_available = 0;
return( 0 ); return (0);
} }
/***************************************************************************** /*****************************************************************************
* adec_Layer1_Stereo * adec_Layer1_Stereo
*****************************************************************************/ *****************************************************************************/
static __inline__ int adec_Layer1_Stereo( adec_thread_t * p_adec ) static __inline__ int adec_Layer1_Stereo (audiodec_t * p_adec)
{ {
p_adec->bit_stream.fifo.buffer = 0; p_adec->bit_stream.buffer = 0;
p_adec->bit_stream.fifo.i_available = 0; p_adec->bit_stream.i_available = 0;
return( 0 ); return (0);
} }
/***************************************************************************** /*****************************************************************************
* adec_Layer2_Mono * adec_Layer2_Mono
*****************************************************************************/ *****************************************************************************/
static __inline__ int adec_Layer2_Mono( adec_thread_t * p_adec ) static __inline__ int adec_Layer2_Mono (audiodec_t * p_adec)
{ {
p_adec->bit_stream.fifo.buffer = 0; p_adec->bit_stream.buffer = 0;
p_adec->bit_stream.fifo.i_available = 0; p_adec->bit_stream.i_available = 0;
return( 0 ); return (0);
} }
/***************************************************************************** /*****************************************************************************
* adec_Layer2_Stereo * adec_Layer2_Stereo
*****************************************************************************/ *****************************************************************************/
static __inline__ int adec_Layer2_Stereo( adec_thread_t * p_adec ) static __inline__ int adec_Layer2_Stereo (audiodec_t * p_adec, s16 * buffer)
{ {
typedef struct requantization_s typedef struct requantization_s
{ {
byte_t i_bits_per_codeword; u8 i_bits_per_codeword;
const float * pf_ungroup; const float * pf_ungroup;
float f_slope; float f_slope;
float f_offset; float f_offset;
...@@ -256,9 +96,9 @@ static __inline__ int adec_Layer2_Stereo( adec_thread_t * p_adec ) ...@@ -256,9 +96,9 @@ static __inline__ int adec_Layer2_Stereo( adec_thread_t * p_adec )
int i_sb, i_nbal; int i_sb, i_nbal;
float f_scalefactor_0, f_scalefactor_1; 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 u8 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 u8 ppi_sblimit[3][11] = ADEC_LAYER2_SBLIMIT;
static const byte_t ppi_nbal[2][32] = ADEC_LAYER2_NBAL; static const u8 ppi_nbal[2][32] = ADEC_LAYER2_NBAL;
static const float pf_ungroup3[3*3*3 * 3] = ADEC_LAYER2_UNGROUP3; 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_ungroup5[5*5*5 * 3] = ADEC_LAYER2_UNGROUP5;
...@@ -273,7 +113,7 @@ static __inline__ int adec_Layer2_Stereo( adec_thread_t * p_adec ) ...@@ -273,7 +113,7 @@ static __inline__ int adec_Layer2_Stereo( adec_thread_t * p_adec )
static int i_sblimit, i_bitrate_per_channel_index; static int i_sblimit, i_bitrate_per_channel_index;
static int pi_scfsi_0[30], pi_scfsi_1[30]; static int pi_scfsi_0[30], pi_scfsi_1[30];
static const byte_t * pi_nbal; static const u8 * pi_nbal;
static float ppf_sample_0[3][32], ppf_sample_1[3][32]; 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_0[30];
static const requantization_t * pp_requantization_1[30]; static const requantization_t * pp_requantization_1[30];
...@@ -286,7 +126,6 @@ static __inline__ int adec_Layer2_Stereo( adec_thread_t * p_adec ) ...@@ -286,7 +126,6 @@ static __inline__ int adec_Layer2_Stereo( adec_thread_t * p_adec )
int i_2nbal, i_gr; int i_2nbal, i_gr;
float f_dummy; float f_dummy;
long l_end_frame;
s16 * p_s16; s16 * p_s16;
int i_need = 0, i_dump = 0; int i_need = 0, i_dump = 0;
...@@ -295,19 +134,17 @@ static __inline__ int adec_Layer2_Stereo( adec_thread_t * p_adec ) ...@@ -295,19 +134,17 @@ static __inline__ int adec_Layer2_Stereo( adec_thread_t * p_adec )
#endif #endif
/* Read the audio frame header and flush the bit buffer */ /* Read the audio frame header and flush the bit buffer */
i_header = p_adec->bit_stream.fifo.buffer; i_header = p_adec->header;
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) */ /* Read the sampling frequency (see ISO/IEC 11172-3 2.4.2.3) */
i_sampling_frequency = (int)((i_header & ADEC_HEADER_SAMPLING_FREQUENCY_MASK) i_sampling_frequency = (int)((i_header & ADEC_HEADER_SAMPLING_FREQUENCY_MASK)
>> ADEC_HEADER_SAMPLING_FREQUENCY_SHIFT); >> ADEC_HEADER_SAMPLING_FREQUENCY_SHIFT);
/* Read the mode (see ISO/IEC 11172-3 2.4.2.3) */ /* 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); 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 a CRC can be found in the frame, get rid of it */
if ( (i_header & ADEC_HEADER_PROTECTION_BIT_MASK) == 0 ) if ((i_header & ADEC_HEADER_PROTECTION_BIT_MASK) == 0)
{ {
GetByte( &p_adec->bit_stream ); NeedBits (&p_adec->bit_stream, 16);
GetByte( &p_adec->bit_stream ); DumpBits (&p_adec->bit_stream, 16);
} }
/* Find out the bitrate per channel index */ /* Find out the bitrate per channel index */
...@@ -316,18 +153,18 @@ static __inline__ int adec_Layer2_Stereo( adec_thread_t * p_adec ) ...@@ -316,18 +153,18 @@ static __inline__ int adec_Layer2_Stereo( adec_thread_t * p_adec )
/* Find out the number of subbands */ /* Find out the number of subbands */
i_sblimit = (int)ppi_sblimit[i_sampling_frequency][i_bitrate_per_channel_index]; i_sblimit = (int)ppi_sblimit[i_sampling_frequency][i_bitrate_per_channel_index];
/* Check if the frame is valid or not */ /* Check if the frame is valid or not */
if ( i_sblimit == 0 ) if (i_sblimit == 0)
{ {
return( 0 ); /* the frame is invalid */ return (0); /* the frame is invalid */
} }
/* Find out the number of bits allocated */ /* Find out the number of bits allocated */
pi_nbal = ppi_nbal[ (i_bitrate_per_channel_index <= 2) ? 0 : 1 ]; 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) */ /* Find out the `bound' subband (see ISO/IEC 11172-3 2.4.2.3) */
if ( i_mode == 1 ) if (i_mode == 1)
{ {
i_bound = (int)(((i_header & ADEC_HEADER_MODE_EXTENSION_MASK) >> (ADEC_HEADER_MODE_EXTENSION_SHIFT - 2)) + 4); i_bound = (int)(((i_header & ADEC_HEADER_MODE_EXTENSION_MASK) >> (ADEC_HEADER_MODE_EXTENSION_SHIFT - 2)) + 4);
if ( i_bound > i_sblimit ) if (i_bound > i_sblimit)
{ {
i_bound = i_sblimit; i_bound = i_sblimit;
} }
...@@ -338,38 +175,38 @@ static __inline__ int adec_Layer2_Stereo( adec_thread_t * p_adec ) ...@@ -338,38 +175,38 @@ static __inline__ int adec_Layer2_Stereo( adec_thread_t * p_adec )
} }
/* Read the allocation information (see ISO/IEC 11172-3 2.4.1.6) */ /* Read the allocation information (see ISO/IEC 11172-3 2.4.1.6) */
for ( i_sb = 0; i_sb < i_bound; i_sb++ ) for (i_sb = 0; i_sb < i_bound; i_sb++)
{ {
i_2nbal = 2 * (i_nbal = (int)pi_nbal[ i_sb ]); i_2nbal = 2 * (i_nbal = (int)pi_nbal[ i_sb ]);
NeedBits( &p_adec->bit_stream, i_2nbal ); NeedBits (&p_adec->bit_stream, i_2nbal);
i_need += i_2nbal; i_need += i_2nbal;
pi_allocation_0[ i_sb ] = (int)(p_adec->bit_stream.fifo.buffer >> (32 - i_nbal)); pi_allocation_0[ i_sb ] = (int)(p_adec->bit_stream.buffer >> (32 - i_nbal));
p_adec->bit_stream.fifo.buffer <<= i_nbal; p_adec->bit_stream.buffer <<= i_nbal;
pi_allocation_1[ i_sb ] = (int)(p_adec->bit_stream.fifo.buffer >> (32 - i_nbal)); pi_allocation_1[ i_sb ] = (int)(p_adec->bit_stream.buffer >> (32 - i_nbal));
p_adec->bit_stream.fifo.buffer <<= i_nbal; p_adec->bit_stream.buffer <<= i_nbal;
p_adec->bit_stream.fifo.i_available -= i_2nbal; p_adec->bit_stream.i_available -= i_2nbal;
i_dump += i_2nbal; i_dump += i_2nbal;
} }
for ( ; i_sb < i_sblimit; i_sb++ ) for (; i_sb < i_sblimit; i_sb++)
{ {
i_nbal = (int)pi_nbal[ i_sb ]; i_nbal = (int)pi_nbal[ i_sb ];
NeedBits( &p_adec->bit_stream, i_nbal ); NeedBits (&p_adec->bit_stream, i_nbal);
i_need += i_nbal; i_need += i_nbal;
pi_allocation_0[ i_sb ] = (int)(p_adec->bit_stream.fifo.buffer >> (32 - i_nbal)); pi_allocation_0[ i_sb ] = (int)(p_adec->bit_stream.buffer >> (32 - i_nbal));
DumpBits( &p_adec->bit_stream, i_nbal ); DumpBits (&p_adec->bit_stream, i_nbal);
i_dump += i_nbal; i_dump += i_nbal;
} }
#define MACRO( p_requantization ) \ #define MACRO(p_requantization) \
for ( i_sb = 0; i_sb < i_bound; i_sb++ ) \ for (i_sb = 0; i_sb < i_bound; i_sb++) \
{ \ { \
if ( pi_allocation_0[i_sb] ) \ if (pi_allocation_0[i_sb]) \
{ \ { \
pp_requantization_0[i_sb] = &((p_requantization)[pi_allocation_0[i_sb]]); \ pp_requantization_0[i_sb] = &((p_requantization)[pi_allocation_0[i_sb]]); \
NeedBits( &p_adec->bit_stream, 2 ); \ NeedBits (&p_adec->bit_stream, 2); \
i_need += 2; \ i_need += 2; \
pi_scfsi_0[i_sb] = (int)(p_adec->bit_stream.fifo.buffer >> (32 - 2)); \ pi_scfsi_0[i_sb] = (int)(p_adec->bit_stream.buffer >> (32 - 2)); \
DumpBits( &p_adec->bit_stream, 2 ); \ DumpBits (&p_adec->bit_stream, 2); \
i_dump += 2; \ i_dump += 2; \
} \ } \
else \ else \
...@@ -379,13 +216,13 @@ static __inline__ int adec_Layer2_Stereo( adec_thread_t * p_adec ) ...@@ -379,13 +216,13 @@ static __inline__ int adec_Layer2_Stereo( adec_thread_t * p_adec )
ppf_sample_0[2][i_sb] = .0; \ ppf_sample_0[2][i_sb] = .0; \
} \ } \
\ \
if ( pi_allocation_1[i_sb] ) \ if (pi_allocation_1[i_sb]) \
{ \ { \
pp_requantization_1[i_sb] = &((p_requantization)[pi_allocation_1[i_sb]]); \ pp_requantization_1[i_sb] = &((p_requantization)[pi_allocation_1[i_sb]]); \
NeedBits( &p_adec->bit_stream, 2 ); \ NeedBits (&p_adec->bit_stream, 2); \
i_need += 2; \ i_need += 2; \
pi_scfsi_1[i_sb] = (int)(p_adec->bit_stream.fifo.buffer >> (32 - 2)); \ pi_scfsi_1[i_sb] = (int)(p_adec->bit_stream.buffer >> (32 - 2)); \
DumpBits( &p_adec->bit_stream, 2 ); \ DumpBits (&p_adec->bit_stream, 2); \
i_dump += 2; \ i_dump += 2; \
} \ } \
else \ else \
...@@ -396,18 +233,18 @@ static __inline__ int adec_Layer2_Stereo( adec_thread_t * p_adec ) ...@@ -396,18 +233,18 @@ static __inline__ int adec_Layer2_Stereo( adec_thread_t * p_adec )
} \ } \
} \ } \
\ \
for ( ; i_sb < i_sblimit; i_sb++ ) \ for (; i_sb < i_sblimit; i_sb++) \
{ \ { \
if ( pi_allocation_0[i_sb] ) \ if (pi_allocation_0[i_sb]) \
{ \ { \
pp_requantization_0[i_sb] = &((p_requantization)[pi_allocation_0[i_sb]]); \ pp_requantization_0[i_sb] = &((p_requantization)[pi_allocation_0[i_sb]]); \
NeedBits( &p_adec->bit_stream, 4 ); \ NeedBits (&p_adec->bit_stream, 4); \
i_need += 4; \ i_need += 4; \
pi_scfsi_0[i_sb] = (int)(p_adec->bit_stream.fifo.buffer >> (32 - 2)); \ pi_scfsi_0[i_sb] = (int)(p_adec->bit_stream.buffer >> (32 - 2)); \
p_adec->bit_stream.fifo.buffer <<= 2; \ p_adec->bit_stream.buffer <<= 2; \
pi_scfsi_1[i_sb] = (int)(p_adec->bit_stream.fifo.buffer >> (32 - 2)); \ pi_scfsi_1[i_sb] = (int)(p_adec->bit_stream.buffer >> (32 - 2)); \
p_adec->bit_stream.fifo.buffer <<= 2; \ p_adec->bit_stream.buffer <<= 2; \
p_adec->bit_stream.fifo.i_available -= 4; \ p_adec->bit_stream.i_available -= 4; \
i_dump += 4; \ i_dump += 4; \
} \ } \
else \ else \
...@@ -422,87 +259,87 @@ static __inline__ int adec_Layer2_Stereo( adec_thread_t * p_adec ) ...@@ -422,87 +259,87 @@ static __inline__ int adec_Layer2_Stereo( adec_thread_t * p_adec )
} }
/* #define MACRO */ /* #define MACRO */
if ( i_bitrate_per_channel_index <= 2 ) if (i_bitrate_per_channel_index <= 2)
{ {
MACRO( p_requantization_cd ) MACRO (p_requantization_cd)
} }
else else
{ {
MACRO( pp_requantization_ab[i_sb] ) MACRO (pp_requantization_ab[i_sb])
} }
#define SWITCH( pi_scfsi, pf_scalefactor_0, pf_scalefactor_1, pf_scalefactor_2 )\ #define SWITCH(pi_scfsi,pf_scalefactor_0,pf_scalefactor_1,pf_scalefactor_2) \
switch ( (pi_scfsi)[i_sb] ) \ switch ((pi_scfsi)[i_sb]) \
{ \ { \
case 0: \ case 0: \
NeedBits( &p_adec->bit_stream, (3*6) ); \ NeedBits (&p_adec->bit_stream, (3*6)); \
i_need += 18; \ i_need += 18; \
(pf_scalefactor_0)[i_sb] = pf_scalefactor[p_adec->bit_stream.fifo.buffer >> (32 - 6)]; \ (pf_scalefactor_0)[i_sb] = pf_scalefactor[p_adec->bit_stream.buffer >> (32 - 6)]; \
p_adec->bit_stream.fifo.buffer <<= 6; \ p_adec->bit_stream.buffer <<= 6; \
(pf_scalefactor_1)[i_sb] = pf_scalefactor[p_adec->bit_stream.fifo.buffer >> (32 - 6)]; \ (pf_scalefactor_1)[i_sb] = pf_scalefactor[p_adec->bit_stream.buffer >> (32 - 6)]; \
p_adec->bit_stream.fifo.buffer <<= 6; \ p_adec->bit_stream.buffer <<= 6; \
(pf_scalefactor_2)[i_sb] = pf_scalefactor[p_adec->bit_stream.fifo.buffer >> (32 - 6)]; \ (pf_scalefactor_2)[i_sb] = pf_scalefactor[p_adec->bit_stream.buffer >> (32 - 6)]; \
p_adec->bit_stream.fifo.buffer <<= 6; \ p_adec->bit_stream.buffer <<= 6; \
p_adec->bit_stream.fifo.i_available -= (3*6); \ p_adec->bit_stream.i_available -= (3*6); \
i_dump += 18; \ i_dump += 18; \
break; \ break; \
\ \
case 1: \ case 1: \
NeedBits( &p_adec->bit_stream, (2*6) ); \ NeedBits (&p_adec->bit_stream, (2*6)); \
i_need += 12; \ i_need += 12; \
(pf_scalefactor_0)[i_sb] = \ (pf_scalefactor_0)[i_sb] = \
(pf_scalefactor_1)[i_sb] = pf_scalefactor[p_adec->bit_stream.fifo.buffer >> (32 - 6)]; \ (pf_scalefactor_1)[i_sb] = pf_scalefactor[p_adec->bit_stream.buffer >> (32 - 6)]; \
p_adec->bit_stream.fifo.buffer <<= 6; \ p_adec->bit_stream.buffer <<= 6; \
(pf_scalefactor_2)[i_sb] = pf_scalefactor[p_adec->bit_stream.fifo.buffer >> (32 - 6)]; \ (pf_scalefactor_2)[i_sb] = pf_scalefactor[p_adec->bit_stream.buffer >> (32 - 6)]; \
p_adec->bit_stream.fifo.buffer <<= 6; \ p_adec->bit_stream.buffer <<= 6; \
p_adec->bit_stream.fifo.i_available -= (2*6); \ p_adec->bit_stream.i_available -= (2*6); \
i_dump += 12; \ i_dump += 12; \
break; \ break; \
\ \
case 2: \ case 2: \
NeedBits( &p_adec->bit_stream, (1*6) ); \ NeedBits (&p_adec->bit_stream, (1*6)); \
i_need += 6; \ i_need += 6; \
(pf_scalefactor_0)[i_sb] = \ (pf_scalefactor_0)[i_sb] = \
(pf_scalefactor_1)[i_sb] = \ (pf_scalefactor_1)[i_sb] = \
(pf_scalefactor_2)[i_sb] = pf_scalefactor[p_adec->bit_stream.fifo.buffer >> (32 - 6)]; \ (pf_scalefactor_2)[i_sb] = pf_scalefactor[p_adec->bit_stream.buffer >> (32 - 6)]; \
DumpBits( &p_adec->bit_stream, (1*6) ); \ DumpBits (&p_adec->bit_stream, (1*6)); \
i_dump += 6; \ i_dump += 6; \
break; \ break; \
\ \
case 3: \ case 3: \
NeedBits( &p_adec->bit_stream, (2*6) ); \ NeedBits (&p_adec->bit_stream, (2*6)); \
i_need += 12; \ i_need += 12; \
(pf_scalefactor_0)[i_sb] = pf_scalefactor[p_adec->bit_stream.fifo.buffer >> (32 - 6)]; \ (pf_scalefactor_0)[i_sb] = pf_scalefactor[p_adec->bit_stream.buffer >> (32 - 6)]; \
p_adec->bit_stream.fifo.buffer <<= 6; \ p_adec->bit_stream.buffer <<= 6; \
(pf_scalefactor_1)[i_sb] = \ (pf_scalefactor_1)[i_sb] = \
(pf_scalefactor_2)[i_sb] = pf_scalefactor[p_adec->bit_stream.fifo.buffer >> (32 - 6)]; \ (pf_scalefactor_2)[i_sb] = pf_scalefactor[p_adec->bit_stream.buffer >> (32 - 6)]; \
p_adec->bit_stream.fifo.buffer <<= 6; \ p_adec->bit_stream.buffer <<= 6; \
p_adec->bit_stream.fifo.i_available -= (2*6); \ p_adec->bit_stream.i_available -= (2*6); \
i_dump += 12; \ i_dump += 12; \
break; \ break; \
} }
/* #define SWITCH */ /* #define SWITCH */
for ( i_sb = 0; i_sb < i_bound; i_sb++ ) for (i_sb = 0; i_sb < i_bound; i_sb++)
{ {
if ( pi_allocation_0[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_0, pf_scalefactor_0_0, pf_scalefactor_0_1, pf_scalefactor_0_2)
} }
if ( pi_allocation_1[i_sb] ) if (pi_allocation_1[i_sb])
{ {
SWITCH( pi_scfsi_1, pf_scalefactor_1_0, pf_scalefactor_1_1, pf_scalefactor_1_2 ) SWITCH (pi_scfsi_1, pf_scalefactor_1_0, pf_scalefactor_1_1, pf_scalefactor_1_2)
} }
} }
for ( ; i_sb < i_sblimit; i_sb++ ) for (; i_sb < i_sblimit; i_sb++)
{ {
if ( pi_allocation_0[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_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 ) SWITCH (pi_scfsi_1, pf_scalefactor_1_0, pf_scalefactor_1_1, pf_scalefactor_1_2)
} }
} }
for ( ; i_sb < 32; i_sb++ ) for (; i_sb < 32; i_sb++)
{ {
ppf_sample_0[0][i_sb] = .0; ppf_sample_0[0][i_sb] = .0;
ppf_sample_0[1][i_sb] = .0; ppf_sample_0[1][i_sb] = .0;
...@@ -512,47 +349,38 @@ static __inline__ int adec_Layer2_Stereo( adec_thread_t * p_adec ) ...@@ -512,47 +349,38 @@ static __inline__ int adec_Layer2_Stereo( adec_thread_t * p_adec )
ppf_sample_1[2][i_sb] = .0; ppf_sample_1[2][i_sb] = .0;
} }
#define NEXT_BUF \ #define GROUPTEST(pp_requantization,ppf_sample,pf_sf) \
/* 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 = ((adec_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]); \ requantization = *((pp_requantization)[i_sb]); \
if ( requantization.pf_ungroup == NULL ) \ if (requantization.pf_ungroup == NULL) \
{ \ { \
NeedBits( &p_adec->bit_stream, requantization.i_bits_per_codeword ); \ NeedBits (&p_adec->bit_stream, requantization.i_bits_per_codeword); \
i_need += 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 * \ (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); \ (p_adec->bit_stream.buffer >> (32 - requantization.i_bits_per_codeword)) + requantization.f_offset); \
DumpBits( &p_adec->bit_stream, requantization.i_bits_per_codeword ); \ DumpBits (&p_adec->bit_stream, requantization.i_bits_per_codeword); \
i_dump += requantization.i_bits_per_codeword; \ i_dump += requantization.i_bits_per_codeword; \
\ \
NeedBits( &p_adec->bit_stream, requantization.i_bits_per_codeword ); \ NeedBits (&p_adec->bit_stream, requantization.i_bits_per_codeword); \
i_need += requantization.i_bits_per_codeword; \ i_need += requantization.i_bits_per_codeword; \
(ppf_sample)[1][i_sb] = f_scalefactor_0 * (requantization.f_slope * \ (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); \ (p_adec->bit_stream.buffer >> (32 - requantization.i_bits_per_codeword)) + requantization.f_offset); \
DumpBits( &p_adec->bit_stream, requantization.i_bits_per_codeword ); \ DumpBits (&p_adec->bit_stream, requantization.i_bits_per_codeword); \
i_dump += requantization.i_bits_per_codeword; \ i_dump += requantization.i_bits_per_codeword; \
\ \
NeedBits( &p_adec->bit_stream, requantization.i_bits_per_codeword ); \ NeedBits (&p_adec->bit_stream, requantization.i_bits_per_codeword); \
i_need += requantization.i_bits_per_codeword; \ i_need += requantization.i_bits_per_codeword; \
(ppf_sample)[2][i_sb] = f_scalefactor_0 * (requantization.f_slope * \ (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); \ (p_adec->bit_stream.buffer >> (32 - requantization.i_bits_per_codeword)) + requantization.f_offset); \
DumpBits( &p_adec->bit_stream, requantization.i_bits_per_codeword ); \ DumpBits (&p_adec->bit_stream, requantization.i_bits_per_codeword); \
i_dump += requantization.i_bits_per_codeword; \ i_dump += requantization.i_bits_per_codeword; \
} \ } \
else \ else \
{ \ { \
NeedBits( &p_adec->bit_stream, requantization.i_bits_per_codeword ); \ NeedBits (&p_adec->bit_stream, requantization.i_bits_per_codeword); \
i_need += requantization.i_bits_per_codeword; \ i_need += requantization.i_bits_per_codeword; \
pf_ungroup = requantization.pf_ungroup + 3 * \ pf_ungroup = requantization.pf_ungroup + 3 * \
(p_adec->bit_stream.fifo.buffer >> (32 - requantization.i_bits_per_codeword)); \ (p_adec->bit_stream.buffer >> (32 - requantization.i_bits_per_codeword)); \
DumpBits( &p_adec->bit_stream, requantization.i_bits_per_codeword ); \ DumpBits (&p_adec->bit_stream, requantization.i_bits_per_codeword); \
i_dump += 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)[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)[1][i_sb] = f_scalefactor_0 * pf_ungroup[1]; \
...@@ -560,67 +388,67 @@ static __inline__ int adec_Layer2_Stereo( adec_thread_t * p_adec ) ...@@ -560,67 +388,67 @@ static __inline__ int adec_Layer2_Stereo( adec_thread_t * p_adec )
} }
/* #define GROUPTEST */ /* #define GROUPTEST */
#define READ_SAMPLE_L2S( pf_scalefactor_0, pf_scalefactor_1, i_grlimit ) \ #define READ_SAMPLE_L2S(pf_scalefactor_0,pf_scalefactor_1,i_grlimit) \
for ( ; i_gr < (i_grlimit); i_gr++ ) \ for (; i_gr < (i_grlimit); i_gr++) \
{ \ { \
for ( i_sb = 0; i_sb < i_bound; i_sb++ ) \ for (i_sb = 0; i_sb < i_bound; i_sb++) \
{ \ { \
if ( pi_allocation_0[i_sb] ) \ if (pi_allocation_0[i_sb]) \
{ \ { \
GROUPTEST( pp_requantization_0, ppf_sample_0, (pf_scalefactor_0) ) \ GROUPTEST (pp_requantization_0, ppf_sample_0, (pf_scalefactor_0)) \
} \ } \
if ( pi_allocation_1[i_sb] ) \ if (pi_allocation_1[i_sb]) \
{ \ { \
GROUPTEST( pp_requantization_1, ppf_sample_1, (pf_scalefactor_1) ) \ GROUPTEST (pp_requantization_1, ppf_sample_1, (pf_scalefactor_1)) \
} \ } \
} \ } \
for ( ; i_sb < i_sblimit; i_sb++ ) \ for (; i_sb < i_sblimit; i_sb++) \
{ \ { \
if ( pi_allocation_0[i_sb] ) \ if (pi_allocation_0[i_sb]) \
{ \ { \
requantization = *(pp_requantization_0[i_sb]); \ requantization = *(pp_requantization_0[i_sb]); \
if ( requantization.pf_ungroup == NULL ) \ if (requantization.pf_ungroup == NULL) \
{ \ { \
NeedBits( &p_adec->bit_stream, requantization.i_bits_per_codeword ); \ NeedBits (&p_adec->bit_stream, requantization.i_bits_per_codeword); \
i_need += 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]) * \ ppf_sample_0[0][i_sb] = (f_scalefactor_0 = (pf_scalefactor_0)[i_sb]) * \
(requantization.f_slope * (f_dummy = \ (requantization.f_slope * (f_dummy = \
(float)(p_adec->bit_stream.fifo.buffer >> (32 - requantization.i_bits_per_codeword))) + \ (float)(p_adec->bit_stream.buffer >> (32 - requantization.i_bits_per_codeword))) + \
requantization.f_offset); \ requantization.f_offset); \
DumpBits( &p_adec->bit_stream, requantization.i_bits_per_codeword ); \ DumpBits (&p_adec->bit_stream, requantization.i_bits_per_codeword); \
i_dump += 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]) * \ ppf_sample_1[0][i_sb] = (f_scalefactor_1 = (pf_scalefactor_1)[i_sb]) * \
(requantization.f_slope * f_dummy + requantization.f_offset); \ (requantization.f_slope * f_dummy + requantization.f_offset); \
\ \
NeedBits( &p_adec->bit_stream, requantization.i_bits_per_codeword ); \ NeedBits (&p_adec->bit_stream, requantization.i_bits_per_codeword); \
i_need += requantization.i_bits_per_codeword; \ i_need += requantization.i_bits_per_codeword; \
ppf_sample_0[1][i_sb] = f_scalefactor_0 * \ ppf_sample_0[1][i_sb] = f_scalefactor_0 * \
(requantization.f_slope * (f_dummy = \ (requantization.f_slope * (f_dummy = \
(float)(p_adec->bit_stream.fifo.buffer >> (32 - requantization.i_bits_per_codeword))) + \ (float)(p_adec->bit_stream.buffer >> (32 - requantization.i_bits_per_codeword))) + \
requantization.f_offset); \ requantization.f_offset); \
DumpBits( &p_adec->bit_stream, requantization.i_bits_per_codeword ); \ DumpBits (&p_adec->bit_stream, requantization.i_bits_per_codeword); \
i_dump += requantization.i_bits_per_codeword; \ i_dump += requantization.i_bits_per_codeword; \
ppf_sample_1[1][i_sb] = f_scalefactor_1 * \ ppf_sample_1[1][i_sb] = f_scalefactor_1 * \
(requantization.f_slope * f_dummy + requantization.f_offset); \ (requantization.f_slope * f_dummy + requantization.f_offset); \
\ \
NeedBits( &p_adec->bit_stream, requantization.i_bits_per_codeword ); \ NeedBits (&p_adec->bit_stream, requantization.i_bits_per_codeword); \
i_need += requantization.i_bits_per_codeword; \ i_need += requantization.i_bits_per_codeword; \
ppf_sample_0[2][i_sb] = f_scalefactor_0 * \ ppf_sample_0[2][i_sb] = f_scalefactor_0 * \
(requantization.f_slope * (f_dummy = \ (requantization.f_slope * (f_dummy = \
(float)(p_adec->bit_stream.fifo.buffer >> (32 - requantization.i_bits_per_codeword))) + \ (float)(p_adec->bit_stream.buffer >> (32 - requantization.i_bits_per_codeword))) + \
requantization.f_offset); \ requantization.f_offset); \
DumpBits( &p_adec->bit_stream, requantization.i_bits_per_codeword ); \ DumpBits (&p_adec->bit_stream, requantization.i_bits_per_codeword); \
i_dump += requantization.i_bits_per_codeword; \ i_dump += requantization.i_bits_per_codeword; \
ppf_sample_1[2][i_sb] = f_scalefactor_1 * \ ppf_sample_1[2][i_sb] = f_scalefactor_1 * \
(requantization.f_slope * f_dummy + requantization.f_offset); \ (requantization.f_slope * f_dummy + requantization.f_offset); \
} \ } \
else \ else \
{ \ { \
NeedBits( &p_adec->bit_stream, requantization.i_bits_per_codeword ); \ NeedBits (&p_adec->bit_stream, requantization.i_bits_per_codeword); \
i_need += requantization.i_bits_per_codeword; \ i_need += requantization.i_bits_per_codeword; \
pf_ungroup = requantization.pf_ungroup + 3 * \ pf_ungroup = requantization.pf_ungroup + 3 * \
(p_adec->bit_stream.fifo.buffer >> (32 - requantization.i_bits_per_codeword)); \ (p_adec->bit_stream.buffer >> (32 - requantization.i_bits_per_codeword)); \
DumpBits( &p_adec->bit_stream, requantization.i_bits_per_codeword ); \ DumpBits (&p_adec->bit_stream, requantization.i_bits_per_codeword); \
i_dump += 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[0][i_sb] = (f_scalefactor_0 = (pf_scalefactor_0)[i_sb]) * pf_ungroup[0]; \
...@@ -634,376 +462,148 @@ static __inline__ int adec_Layer2_Stereo( adec_thread_t * p_adec ) ...@@ -634,376 +462,148 @@ static __inline__ int adec_Layer2_Stereo( adec_thread_t * p_adec )
} \ } \
} \ } \
\ \
/* fprintf(stderr, "%p", p_s16); */ \ DCT32 (ppf_sample_0[0], &p_adec->bank_0); \
DCT32( ppf_sample_0[0], &p_adec->bank_0 ); \ PCM (&p_adec->bank_0, &p_s16, 2); \
PCM( &p_adec->bank_0, &p_s16, 2 ); \
/* fprintf(stderr, " %p", p_s16); */ \
p_s16 -= 63; \ p_s16 -= 63; \
/* fprintf(stderr, " %p\n", p_s16); */ \
\ \
/* fprintf(stderr, "%p", p_s16); */ \ DCT32 (ppf_sample_1[0], &p_adec->bank_1); \
DCT32( ppf_sample_1[0], &p_adec->bank_1 ); \ PCM (&p_adec->bank_1, &p_s16, 2); \
PCM( &p_adec->bank_1, &p_s16, 2 ); \
/* fprintf(stderr, " %p", p_s16); */ \
p_s16 -= 1; \ p_s16 -= 1; \
/* fprintf(stderr, " %p\n", p_s16); */ \
\ \
/* fprintf(stderr, "%p", p_s16); */ \ DCT32 (ppf_sample_0[1], &p_adec->bank_0); \
DCT32( ppf_sample_0[1], &p_adec->bank_0 ); \ PCM (&p_adec->bank_0, &p_s16, 2); \
PCM( &p_adec->bank_0, &p_s16, 2 ); \
/* fprintf(stderr, " %p", p_s16); */ \
p_s16 -= 63; \ p_s16 -= 63; \
/* fprintf(stderr, " %p\n", p_s16); */ \
\ \
/* fprintf(stderr, "%p", p_s16); */ \ DCT32 (ppf_sample_1[1], &p_adec->bank_1); \
DCT32( ppf_sample_1[1], &p_adec->bank_1 ); \ PCM (&p_adec->bank_1, &p_s16, 2); \
PCM( &p_adec->bank_1, &p_s16, 2 ); \
/* fprintf(stderr, " %p", p_s16); */ \
p_s16 -= 1; \ p_s16 -= 1; \
/* fprintf(stderr, " %p\n", p_s16); */ \
\ \
/* fprintf(stderr, "%p", p_s16); */ \ DCT32 (ppf_sample_0[2], &p_adec->bank_0); \
DCT32( ppf_sample_0[2], &p_adec->bank_0 ); \ PCM (&p_adec->bank_0, &p_s16, 2); \
PCM( &p_adec->bank_0, &p_s16, 2 ); \
/* fprintf(stderr, " %p", p_s16); */ \
p_s16 -= 63; \ p_s16 -= 63; \
/* fprintf(stderr, " %p\n", p_s16); */ \
\ \
/* fprintf(stderr, "%p", p_s16); */ \ DCT32 (ppf_sample_1[2], &p_adec->bank_1); \
DCT32( ppf_sample_1[2], &p_adec->bank_1 ); \ PCM (&p_adec->bank_1, &p_s16, 2); \
PCM( &p_adec->bank_1, &p_s16, 2 ); \
/* fprintf(stderr, " %p", p_s16); */ \
p_s16 -= 1; \ p_s16 -= 1; \
/* fprintf(stderr, " %p\n", p_s16); */ \
} }
/* #define READ_SAMPLE_L2S */ /* #define READ_SAMPLE_L2S */
l_end_frame = p_adec->p_aout_fifo->l_end_frame;
i_gr = 0; i_gr = 0;
p_s16 = buffer;
NEXT_BUF READ_SAMPLE_L2S (pf_scalefactor_0_0, pf_scalefactor_1_0, 4)
READ_SAMPLE_L2S( pf_scalefactor_0_0, pf_scalefactor_1_0, 2 ) READ_SAMPLE_L2S (pf_scalefactor_0_1, pf_scalefactor_1_1, 8)
READ_SAMPLE_L2S (pf_scalefactor_0_2, pf_scalefactor_1_2, 12)
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 p_adec->bit_stream.buffer = 0;
READ_SAMPLE_L2S( pf_scalefactor_0_2, pf_scalefactor_1_2, 12 ) p_adec->bit_stream.i_available = 0;
return (6);
#if 0
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);
#endif
p_adec->bit_stream.fifo.buffer = 0;
p_adec->bit_stream.fifo.i_available = 0;
return( 6 );
} }
/***************************************************************************** /**** wkn ****/
* 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 )
{
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 */
vlc_mutex_lock( &p_adec->fifo.data_lock );
while ( DECODER_FIFO_ISEMPTY(p_adec->fifo) )
{
if ( p_adec->b_die )
{
vlc_mutex_unlock( &p_adec->fifo.data_lock );
return( -1 );
}
vlc_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.p_byte = p_adec->bit_stream.p_ts->buffer + p_adec->bit_stream.p_ts->i_payload_start;
p_adec->bit_stream.p_end = p_adec->bit_stream.p_ts->buffer + p_adec->bit_stream.p_ts->i_payload_end;
vlc_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.i_channels = 1;
aout_fifo.b_stereo = 0;
}
else
{
intf_DbgMsg("adec debug: mode == stereo\n");
aout_fifo.i_type = AOUT_ADEC_STEREO_FIFO;
aout_fifo.i_channels = 2;
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;
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 );
}
aout_fifo.l_frame_size = ADEC_FRAME_SIZE;
/* Creating the audio output fifo */
if ( (p_adec->p_aout_fifo = aout_CreateFifo(p_adec->p_aout, &aout_fifo)) == NULL )
{
return( -1 );
}
intf_DbgMsg("adec debug: audio decoder thread %p initialized\n", p_adec); int adec_init (audiodec_t * p_adec)
return( 0 ); {
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;
return 0;
} }
/***************************************************************************** int adec_sync_frame (audiodec_t * p_adec, adec_sync_info_t * p_sync_info)
* 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 )
{ {
#if 0 static int mpeg1_sample_rate[3] = {44100, 48000, 32000};
static const int pi_framesize[512] = ADEC_FRAME_SIZE; static int mpeg1_layer1_bit_rate[15] = {
int i_header; 0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448
int i_framesize; };
int i_dummy; static int mpeg1_layer2_bit_rate[15] = {
#endif 0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384
};
intf_DbgMsg("adec debug: running audio decoder thread (%p) (pid == %i)\n", p_adec, getpid()); static int mpeg2_layer1_bit_rate[15] = {
0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256
msleep( INPUT_PTS_DELAY ); };
static int mpeg2_layer2_bit_rate[15] = {
/* Initializing the audio decoder thread */ 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160
if ( InitThread(p_adec) ) };
{ u32 header;
p_adec->b_error = 1; int index;
} int * bit_rate_table;
int sample_rate;
/* Audio decoder thread's main loop */ int bit_rate;
while ( (!p_adec->b_die) && (!p_adec->b_error) ) int frame_size;
{
switch ( (p_adec->bit_stream.fifo.buffer & ADEC_HEADER_LAYER_MASK) >> ADEC_HEADER_LAYER_SHIFT ) p_adec->bit_stream.total_bytes_read = 0;
{ header = GetByte (&p_adec->bit_stream) << 24;
/* Reserved */ header |= GetByte (&p_adec->bit_stream) << 16;
case 0: header |= GetByte (&p_adec->bit_stream) << 8;
intf_DbgMsg("adec debug: layer == 0 (reserved)\n"); header |= GetByte (&p_adec->bit_stream);
p_adec->bit_stream.fifo.buffer = 0;
p_adec->bit_stream.fifo.i_available = 0; p_adec->header = header;
/* basic header check : sync word, no emphasis */
if ((header & 0xfff00003) != 0xfff00000)
return 1;
index = (header >> 10) & 3; /* sample rate index */
if (index > 2)
return 1;
sample_rate = mpeg1_sample_rate[index];
switch ((header >> 17) & 7) {
case 2: /* mpeg 2, layer 2 */
sample_rate >>= 1; /* half sample rate for mpeg2 */
bit_rate_table = mpeg2_layer2_bit_rate;
break; break;
case 3: /* mpeg 2, layer 1 */
/* Layer III */ sample_rate >>= 1; /* half sample rate for mpeg2 */
case 1: bit_rate_table = mpeg2_layer1_bit_rate;
p_adec->bit_stream.fifo.buffer = 0;
p_adec->bit_stream.fifo.i_available = 0;
break;
/* Layer II */
case 2:
if ( (p_adec->bit_stream.fifo.buffer & ADEC_HEADER_MODE_MASK) == ADEC_HEADER_MODE_MASK )
{
adec_Layer2_Mono( p_adec );
}
else
{
/* Waiting until there is enough free space in the audio output fifo
* in order to store the new decoded frames */
vlc_mutex_lock( &p_adec->p_aout_fifo->data_lock );
/* adec_Layer2_Stereo() produces 6 output frames (2*1152/384)...
* If these 6 frames were recorded in the audio output fifo, the
* l_end_frame index would be incremented 6 times. But, if after
* this operation the audio output fifo contains less than 6 frames,
* it would mean that we had not enough room to store the 6 frames :-P */
while ( (((p_adec->p_aout_fifo->l_end_frame + 6) - p_adec->p_aout_fifo->l_start_frame) & AOUT_FIFO_SIZE) < 6 ) /* XXX?? */
{
vlc_cond_wait( &p_adec->p_aout_fifo->data_wait, &p_adec->p_aout_fifo->data_lock );
}
if ( DECODER_FIFO_START(p_adec->fifo)->b_has_pts )
{
p_adec->p_aout_fifo->date[p_adec->p_aout_fifo->l_end_frame] = DECODER_FIFO_START(p_adec->fifo)->i_pts;
DECODER_FIFO_START(p_adec->fifo)->b_has_pts = 0;
}
else
{
p_adec->p_aout_fifo->date[p_adec->p_aout_fifo->l_end_frame] = LAST_MDATE;
}
vlc_mutex_unlock( &p_adec->p_aout_fifo->data_lock );
/* Decoding the frames */
if ( adec_Layer2_Stereo(p_adec) )
{
vlc_mutex_lock( &p_adec->p_aout_fifo->data_lock );
/* Frame 1 */
p_adec->p_aout_fifo->l_end_frame = (p_adec->p_aout_fifo->l_end_frame + 1) & 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 = (p_adec->p_aout_fifo->l_end_frame + 1) & 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 = (p_adec->p_aout_fifo->l_end_frame + 1) & 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 = (p_adec->p_aout_fifo->l_end_frame + 1) & 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 = (p_adec->p_aout_fifo->l_end_frame + 1) & 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 = (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 );
}
}
break; break;
case 6: /* mpeg1, layer 2 */
/* Layer I */ bit_rate_table = mpeg1_layer2_bit_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; break;
case 7: /* mpeg1, layer 1 */
default: bit_rate_table = mpeg1_layer1_bit_rate;
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; break;
} default: /* invalid layer */
FindHeader( p_adec ); return 1;
} }
/* If b_error is set, the audio decoder thread enters the error loop */ index = (header >> 12) & 15; /* bit rate index */
if ( p_adec->b_error ) if (index > 14)
{ return 1;
ErrorThread( p_adec ); bit_rate = bit_rate_table[index];
}
/* End of the audio decoder thread */ p_sync_info->sample_rate = sample_rate;
EndThread( p_adec ); p_sync_info->bit_rate = bit_rate;
}
/***************************************************************************** if ((header & 0x60000) == 0x60000) { /* layer 1 */
* ErrorThread : audio decoder's RunThread() error loop frame_size = 48000 * bit_rate / sample_rate;
***************************************************************************** if (header & 0x200) /* padding */
* This function is called when an error occured during thread main's loop. The frame_size += 4;
* thread can still receive feed, but must be ready to terminate as soon as } else { /* layer >1 */
* possible. frame_size = 144000 * bit_rate / sample_rate;
*****************************************************************************/ if (header & 0x200) /* padding */
static void ErrorThread( adec_thread_t *p_adec ) frame_size ++;
{
/* We take the lock, because we are going to read/write the start/end
* indexes of the decoder fifo */
vlc_mutex_lock( &p_adec->fifo.data_lock );
/* Wait until a `die' order is sent */
while( !p_adec->b_die )
{
/* Trash all received PES packets */
while( !DECODER_FIFO_ISEMPTY(p_adec->fifo) )
{
input_NetlistFreePES( p_adec->bit_stream.p_input, DECODER_FIFO_START(p_adec->fifo) );
DECODER_FIFO_INCSTART( p_adec->fifo );
} }
/* Waiting for the input thread to put new PES packets in the fifo */ p_sync_info->frame_size = frame_size;
vlc_cond_wait( &p_adec->fifo.data_wait, &p_adec->fifo.data_lock ); p_adec->frame_size = frame_size;
}
/* We can release the lock before leaving */ return 0;
vlc_mutex_unlock( &p_adec->fifo.data_lock );
} }
/***************************************************************************** int adec_decode_frame (audiodec_t * p_adec, s16 * buffer)
* EndThread : audio decoder thread destruction
*****************************************************************************
* This function is called when the thread ends after a sucessfull
* initialization.
*****************************************************************************/
static void EndThread( adec_thread_t *p_adec )
{ {
intf_DbgMsg("adec debug: destroying audio decoder thread %p\n", p_adec); p_adec->bit_stream.i_available = 0;
/* If the audio output fifo was created, we destroy it */ adec_Layer2_Stereo (p_adec, buffer);
if ( p_adec->p_aout_fifo != NULL )
{
aout_DestroyFifo( p_adec->p_aout_fifo );
/* Make sure the output thread leaves the NextFrame() function */ if (p_adec->bit_stream.total_bytes_read > p_adec->frame_size)
vlc_mutex_lock( &(p_adec->p_aout_fifo->data_lock) ); return 1;
vlc_cond_signal( &(p_adec->p_aout_fifo->data_wait) );
vlc_mutex_unlock( &(p_adec->p_aout_fifo->data_lock) ); while (p_adec->bit_stream.total_bytes_read < p_adec->frame_size)
} GetByte (&p_adec->bit_stream);
/* Destroy descriptor */
free( p_adec );
intf_DbgMsg("adec debug: audio decoder thread %p destroyed\n", p_adec); return 0;
} }
/*****************************************************************************
* audio_decoder.c: MPEG1 Layer I-II audio decoder thread
*****************************************************************************
* Copyright (C) 1999, 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-1307, USA.
*****************************************************************************/
/*
* TODO :
*
* - optimiser les NeedBits() et les GetBits() du code l o c'est possible ;
* - vlc_cond_signal() / vlc_cond_wait() ;
*
*/
/*****************************************************************************
* Preamble
*****************************************************************************/
#include "defs.h"
#include <unistd.h> /* getpid() */
#include <stdio.h> /* "intf_msg.h" */
#include <stdlib.h> /* malloc(), free() */
#include <sys/types.h> /* on BSD, uio.h needs types.h */
#include <sys/uio.h> /* "input.h" */
#include "threads.h"
#include "common.h"
#include "config.h"
#include "mtime.h"
#include "plugins.h"
#include "debug.h" /* "input_netlist.h" */
#include "intf_msg.h" /* intf_DbgMsg(), intf_ErrMsg() */
#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_constants.h"
#include "audio_decoder.h"
#include "audio_decoder_thread.h"
#include "audio_math.h" /* DCT32(), PCM() */
#define ADEC_FRAME_SIZE (2*1152)
/*****************************************************************************
* 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)
{
adec_thread_t * p_adec;
intf_DbgMsg ("adec debug: creating audio decoder thread\n");
/* Allocate the memory needed to store the thread's structure */
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;
}
/*
* 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 */
vlc_mutex_init (&p_adec->fifo.data_lock);
vlc_cond_init (&p_adec->fifo.data_wait);
p_adec->fifo.i_start = 0;
p_adec->fifo.i_end = 0;
/* Initialize the bit stream structure */
p_adec->p_input = p_input;
/*
* Initialize the decoder properties
*/
adec_init (&p_adec->audio_decoder);
/*
* Initialize the output properties
*/
p_adec->p_aout = p_input->p_aout;
p_adec->p_aout_fifo = NULL;
/* Spawn the audio decoder thread */
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\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;
/* Make sure the decoder thread leaves the GetByte() function */
vlc_mutex_lock (&(p_adec->fifo.data_lock));
vlc_cond_signal (&(p_adec->fifo.data_wait));
vlc_mutex_unlock (&(p_adec->fifo.data_lock));
/* Waiting for the decoder thread to exit */
/* Remove this as soon as the "status" flag is implemented */
vlc_thread_join (p_adec->thread_id);
}
/*****************************************************************************
* 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)
{
aout_fifo_t aout_fifo;
adec_byte_stream_t * byte_stream;
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 */
vlc_mutex_lock (&p_adec->fifo.data_lock);
while (DECODER_FIFO_ISEMPTY(p_adec->fifo)) {
if (p_adec->b_die) {
vlc_mutex_unlock (&p_adec->fifo.data_lock);
return -1;
}
vlc_cond_wait (&p_adec->fifo.data_wait, &p_adec->fifo.data_lock);
}
p_adec->p_ts = DECODER_FIFO_START (p_adec->fifo)->p_first_ts;
byte_stream = adec_byte_stream (&p_adec->audio_decoder);
byte_stream->p_byte =
p_adec->p_ts->buffer + p_adec->p_ts->i_payload_start;
byte_stream->p_end =
p_adec->p_ts->buffer + p_adec->p_ts->i_payload_end;
byte_stream->info = p_adec;
vlc_mutex_unlock (&p_adec->fifo.data_lock);
aout_fifo.i_type = AOUT_ADEC_STEREO_FIFO;
aout_fifo.i_channels = 2;
aout_fifo.b_stereo = 1;
aout_fifo.l_frame_size = ADEC_FRAME_SIZE;
/* Creating the audio output fifo */
if ((p_adec->p_aout_fifo = aout_CreateFifo(p_adec->p_aout, &aout_fifo)) == NULL) {
return -1;
}
intf_DbgMsg ("adec debug: audio decoder thread %p initialized\n", 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)
{
int sync;
intf_DbgMsg ("adec debug: running audio decoder thread (%p) (pid == %i)\n", p_adec, getpid());
msleep (INPUT_PTS_DELAY);
/* Initializing the audio decoder thread */
if (InitThread (p_adec)) {
p_adec->b_error = 1;
}
sync = 0;
/* Audio decoder thread's main loop */
while ((!p_adec->b_die) && (!p_adec->b_error)) {
s16 * buffer;
adec_sync_info_t sync_info;
if (!sync) { /* have to find a synchro point */
adec_byte_stream_t * p_byte_stream;
printf ("sync\n");
p_adec->align = 0;
p_byte_stream = adec_byte_stream (&p_adec->audio_decoder);
do {
adec_byte_stream_next (p_byte_stream);
} while ((!p_adec->align) &&
(!p_adec->b_die) &&
(!p_adec->b_error));
sync = 1;
}
if (DECODER_FIFO_START(p_adec->fifo)->b_has_pts) {
p_adec->p_aout_fifo->date[p_adec->p_aout_fifo->l_end_frame] = DECODER_FIFO_START(p_adec->fifo)->i_pts;
DECODER_FIFO_START(p_adec->fifo)->b_has_pts = 0;
} else {
p_adec->p_aout_fifo->date[p_adec->p_aout_fifo->l_end_frame] = LAST_MDATE;
}
if (adec_sync_frame (&p_adec->audio_decoder, &sync_info)) {
sync = 0;
goto bad_frame;
}
p_adec->p_aout_fifo->l_rate = sync_info.sample_rate;
buffer = ((s16 *)p_adec->p_aout_fifo->buffer) + (p_adec->p_aout_fifo->l_end_frame * ADEC_FRAME_SIZE);
if (adec_decode_frame (&p_adec->audio_decoder, buffer)) {
sync = 0;
goto bad_frame;
}
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 (p_adec->b_error) {
ErrorThread (p_adec);
}
/* End of the audio decoder thread */
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)
{
/* We take the lock, because we are going to read/write the start/end
* indexes of the decoder fifo */
vlc_mutex_lock (&p_adec->fifo.data_lock);
/* Wait until a `die' order is sent */
while (!p_adec->b_die) {
/* Trash all received PES packets */
while (!DECODER_FIFO_ISEMPTY(p_adec->fifo)) {
input_NetlistFreePES (p_adec->p_input, DECODER_FIFO_START(p_adec->fifo));
DECODER_FIFO_INCSTART (p_adec->fifo);
}
/* Waiting for the input thread to put new PES packets in the fifo */
vlc_cond_wait (&p_adec->fifo.data_wait, &p_adec->fifo.data_lock);
}
/* We can release the lock before leaving */
vlc_mutex_unlock (&p_adec->fifo.data_lock);
}
/*****************************************************************************
* EndThread : audio decoder thread destruction
*****************************************************************************
* This function is called when the thread ends after a sucessfull
* initialization.
*****************************************************************************/
static void EndThread (adec_thread_t *p_adec)
{
intf_DbgMsg ("adec debug: destroying audio decoder thread %p\n", p_adec);
/* If the audio output fifo was created, we destroy it */
if (p_adec->p_aout_fifo != NULL) {
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);
intf_DbgMsg ("adec debug: audio decoder thread %p destroyed\n", 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_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 */
vlc_mutex_lock (&p_adec->fifo.data_lock);
/* Is the input thread dying ? */
if (p_adec->p_input->b_die) {
vlc_mutex_unlock (&(p_adec->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. */
input_NetlistFreePES (p_adec->p_input, DECODER_FIFO_START(p_adec->fifo));
DECODER_FIFO_INCSTART (p_adec->fifo);
while (DECODER_FIFO_ISEMPTY(p_adec->fifo)) {
vlc_cond_wait (&p_adec->fifo.data_wait, &p_adec->fifo.data_lock);
if (p_adec->p_input->b_die) {
vlc_mutex_unlock (&(p_adec->fifo.data_lock));
return;
}
}
/* The next byte could be found in the next PES packet */
p_adec->p_ts = DECODER_FIFO_START (p_adec->fifo)->p_first_ts;
if (DECODER_FIFO_START (p_adec->fifo)->b_data_alignment)
p_adec->align = 1;
/* We can release the fifo's data lock */
vlc_mutex_unlock (&p_adec->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_ts = p_adec->p_ts->p_next_ts;
}
} while (p_adec->p_ts->i_payload_start == p_adec->p_ts->i_payload_end);
/* We've found a TS packet which contains interesting data... */
p_byte_stream->p_byte =
p_adec->p_ts->buffer + p_adec->p_ts->i_payload_start;
p_byte_stream->p_end =
p_adec->p_ts->buffer + p_adec->p_ts->i_payload_end;
}
...@@ -21,29 +21,7 @@ ...@@ -21,29 +21,7 @@
* Boston, MA 02111-1307, USA. * Boston, MA 02111-1307, USA.
*****************************************************************************/ *****************************************************************************/
/***************************************************************************** #include "int_types.h"
* Preamble
*****************************************************************************/
#include "defs.h"
#include <stdio.h> /* "intf_msg.h" */
#include <stdlib.h> /* malloc(), free() */
#include <sys/types.h> /* on BSD, uio.h needs types.h */
#include <sys/uio.h> /* "input.h" */
#include "config.h"
#include "common.h"
#include "threads.h"
#include "mtime.h" /* mtime_t */
#include "plugins.h"
#include "intf_msg.h" /* intf_DbgMsg(), intf_ErrMsg() */
#include "input.h" /* pes_packet_t (for decoder_fifo.h) */
#include "decoder_fifo.h" /* decoder_fifo_t (for audio_decoder.h) */
#include "audio_output.h" /* aout_fifo_t (for audio_decoder.h) */
#include "audio_decoder.h" /* adec_bank_t */ #include "audio_decoder.h" /* adec_bank_t */
/***************************************************************************** /*****************************************************************************
...@@ -135,7 +113,7 @@ void DCT32(float *x, adec_bank_t *b) ...@@ -135,7 +113,7 @@ void DCT32(float *x, adec_bank_t *b)
t32 = c32 * (x[30] - x[1]); t32 = c32 * (x[30] - x[1]);
t16 = x[30] + x[1]; t16 = x[30] + x[1];
/* 2nd stage */ /* 2nd stage */
tt9 = c9 * (t1 - t9 ); tt9 = c9 * (t1 - t9);
tt1 = t1 + t9; tt1 = t1 + t9;
tt10 = c10 * (t2 - t10); tt10 = c10 * (t2 - t10);
tt2 = t2 + t10; tt2 = t2 + t10;
...@@ -168,13 +146,13 @@ void DCT32(float *x, adec_bank_t *b) ...@@ -168,13 +146,13 @@ void DCT32(float *x, adec_bank_t *b)
tt32 = c16 * (t24 - t32); tt32 = c16 * (t24 - t32);
tt24 = t24 + t32; tt24 = t24 + t32;
/* 3rd stage */ /* 3rd stage */
t5 = c5 * (tt1 - tt5 ); t5 = c5 * (tt1 - tt5);
t1 = tt1 + tt5; t1 = tt1 + tt5;
t6 = c6 * (tt2 - tt6 ); t6 = c6 * (tt2 - tt6);
t2 = tt2 + tt6; t2 = tt2 + tt6;
t7 = c7 * (tt3 - tt7 ); t7 = c7 * (tt3 - tt7);
t3 = tt3 + tt7; t3 = tt3 + tt7;
t8 = c8 * (tt4 - tt8 ); t8 = c8 * (tt4 - tt8);
t4 = tt4 + tt8; t4 = tt4 + tt8;
t13 = c5 * (tt9 - tt13); t13 = c5 * (tt9 - tt13);
t9 = tt9 + tt13; t9 = tt9 + tt13;
...@@ -201,13 +179,13 @@ void DCT32(float *x, adec_bank_t *b) ...@@ -201,13 +179,13 @@ void DCT32(float *x, adec_bank_t *b)
t32 = c8 * (tt28 - tt32); t32 = c8 * (tt28 - tt32);
t28 = tt28 + tt32; t28 = tt28 + tt32;
/* 4th stage */ /* 4th stage */
tt3 = c3 * (t1 - t3 ); tt3 = c3 * (t1 - t3);
tt1 = t1 + t3; tt1 = t1 + t3;
tt4 = c4 * (t2 - t4 ); tt4 = c4 * (t2 - t4);
tt2 = t2 + t4; tt2 = t2 + t4;
tt7 = c3 * (t5 - t7 ); tt7 = c3 * (t5 - t7);
tt5 = t5 + t7; tt5 = t5 + t7;
tt8 = c4 * (t6 - t8 ); tt8 = c4 * (t6 - t8);
tt6 = t6 + t8; tt6 = t6 + t8;
tt11 = c3 * (t9 - t11); tt11 = c3 * (t9 - t11);
tt9 = t9 + t11; tt9 = t9 + t11;
...@@ -237,13 +215,13 @@ void DCT32(float *x, adec_bank_t *b) ...@@ -237,13 +215,13 @@ void DCT32(float *x, adec_bank_t *b)
/* Begin to split the result of the DCT (t1 to t32) in the filter bank */ /* Begin to split the result of the DCT (t1 to t32) in the filter bank */
x = b->actual + b->pos; x = b->actual + b->pos;
y = (b->actual == b->v1 ? b->v2 : b->v1) + b->pos; y = (b->actual == b->v1 ? b->v2 : b->v1) + b->pos;
x[0] = -(y[0] = c2 * (tt1 - tt2 )); /* t17 */ x[0] = -(y[0] = c2 * (tt1 - tt2)); /* t17 */
x[256] = 0; y[256] = tt1 + tt2; /* t1 */ x[256] = 0; y[256] = tt1 + tt2; /* t1 */
t25 = c2 * (tt3 - tt4 ); t25 = c2 * (tt3 - tt4);
t9 = tt3 + tt4; t9 = tt3 + tt4;
t21 = c2 * (tt5 - tt6 ); t21 = c2 * (tt5 - tt6);
t5 = tt5 + tt6; t5 = tt5 + tt6;
t29 = c2 * (tt7 - tt8 ); t29 = c2 * (tt7 - tt8);
t13 = tt7 + tt8; t13 = tt7 + tt8;
t19 = c2 * (tt9 - tt10); t19 = c2 * (tt9 - tt10);
t3 = tt9 + tt10; t3 = tt9 + tt10;
...@@ -478,7 +456,7 @@ void PCM(adec_bank_t *b, s16 **pcm, int jump) ...@@ -478,7 +456,7 @@ void PCM(adec_bank_t *b, s16 **pcm, int jump)
switch(b->pos) { switch(b->pos) {
case 0: case 0:
v = b->actual; v = b->actual;
for(i=0; i<32; i++) { for (i=0; i<32; i++) {
tmp = *f++ * *v; tmp = *f++ * *v;
v += 15; v += 15;
tmp += *f++ * *v--; tmp += *f++ * *v--;
...@@ -495,11 +473,11 @@ void PCM(adec_bank_t *b, s16 **pcm, int jump) ...@@ -495,11 +473,11 @@ void PCM(adec_bank_t *b, s16 **pcm, int jump)
tmp += *f++ * *v--; tmp += *f++ * *v--;
tmp += *f++ * *v--; tmp += *f++ * *v--;
tmp += *f++ * *v--; tmp += *f++ * *v--;
if((tmp += *f++ * *v) > 32767) if ((tmp += *f++ * *v) > 32767)
/* ceiling saturation */ /* ceiling saturation */
**pcm = 0x7FFF; **pcm = 0x7FFF;
else else
if(tmp < -32768) if (tmp < -32768)
/* floor saturation */ /* floor saturation */
**pcm = 0x8000; **pcm = 0x8000;
else else
...@@ -510,7 +488,7 @@ void PCM(adec_bank_t *b, s16 **pcm, int jump) ...@@ -510,7 +488,7 @@ void PCM(adec_bank_t *b, s16 **pcm, int jump)
break; break;
case 1: case 1:
v = b->actual + 1; v = b->actual + 1;
for(i=0; i<32; i++) { for (i=0; i<32; i++) {
tmp = *f++ * *v--; tmp = *f++ * *v--;
tmp += *f++ * *v; tmp += *f++ * *v;
v += 15; v += 15;
...@@ -527,10 +505,10 @@ void PCM(adec_bank_t *b, s16 **pcm, int jump) ...@@ -527,10 +505,10 @@ void PCM(adec_bank_t *b, s16 **pcm, int jump)
tmp += *f++ * *v--; tmp += *f++ * *v--;
tmp += *f++ * *v--; tmp += *f++ * *v--;
tmp += *f++ * *v--; tmp += *f++ * *v--;
if((tmp += *f++ * *v) > 32767) if ((tmp += *f++ * *v) > 32767)
**pcm = 0x7FFF; **pcm = 0x7FFF;
else else
if(tmp < -32768) if (tmp < -32768)
**pcm = 0x8000; **pcm = 0x8000;
else else
**pcm = (s16)tmp; **pcm = (s16)tmp;
...@@ -540,7 +518,7 @@ void PCM(adec_bank_t *b, s16 **pcm, int jump) ...@@ -540,7 +518,7 @@ void PCM(adec_bank_t *b, s16 **pcm, int jump)
break; break;
case 2: case 2:
v = b->actual + 2; v = b->actual + 2;
for(i=0; i<32; i++) { for (i=0; i<32; i++) {
tmp = *f++ * *v--; tmp = *f++ * *v--;
tmp += *f++ * *v--; tmp += *f++ * *v--;
tmp += *f++ * *v; tmp += *f++ * *v;
...@@ -557,10 +535,10 @@ void PCM(adec_bank_t *b, s16 **pcm, int jump) ...@@ -557,10 +535,10 @@ void PCM(adec_bank_t *b, s16 **pcm, int jump)
tmp += *f++ * *v--; tmp += *f++ * *v--;
tmp += *f++ * *v--; tmp += *f++ * *v--;
tmp += *f++ * *v--; tmp += *f++ * *v--;
if((tmp += *f++ * *v) > 32767) if ((tmp += *f++ * *v) > 32767)
**pcm = 0x7FFF; **pcm = 0x7FFF;
else else
if(tmp < -32768) if (tmp < -32768)
**pcm = 0x8000; **pcm = 0x8000;
else else
**pcm = (s16)tmp; **pcm = (s16)tmp;
...@@ -570,7 +548,7 @@ void PCM(adec_bank_t *b, s16 **pcm, int jump) ...@@ -570,7 +548,7 @@ void PCM(adec_bank_t *b, s16 **pcm, int jump)
break; break;
case 3: case 3:
v = b->actual + 3; v = b->actual + 3;
for(i=0; i<32; i++) { for (i=0; i<32; i++) {
tmp = *f++ * *v--; tmp = *f++ * *v--;
tmp += *f++ * *v--; tmp += *f++ * *v--;
tmp += *f++ * *v--; tmp += *f++ * *v--;
...@@ -587,10 +565,10 @@ void PCM(adec_bank_t *b, s16 **pcm, int jump) ...@@ -587,10 +565,10 @@ void PCM(adec_bank_t *b, s16 **pcm, int jump)
tmp += *f++ * *v--; tmp += *f++ * *v--;
tmp += *f++ * *v--; tmp += *f++ * *v--;
tmp += *f++ * *v--; tmp += *f++ * *v--;
if((tmp += *f++ * *v) > 32767) if ((tmp += *f++ * *v) > 32767)
**pcm = 0x7FFF; **pcm = 0x7FFF;
else else
if(tmp < -32768) if (tmp < -32768)
**pcm = 0x8000; **pcm = 0x8000;
else else
**pcm = (s16)tmp; **pcm = (s16)tmp;
...@@ -600,7 +578,7 @@ void PCM(adec_bank_t *b, s16 **pcm, int jump) ...@@ -600,7 +578,7 @@ void PCM(adec_bank_t *b, s16 **pcm, int jump)
break; break;
case 4: case 4:
v = b->actual + 4; v = b->actual + 4;
for(i=0; i<32; i++) { for (i=0; i<32; i++) {
tmp = *f++ * *v--; tmp = *f++ * *v--;
tmp += *f++ * *v--; tmp += *f++ * *v--;
tmp += *f++ * *v--; tmp += *f++ * *v--;
...@@ -617,10 +595,10 @@ void PCM(adec_bank_t *b, s16 **pcm, int jump) ...@@ -617,10 +595,10 @@ void PCM(adec_bank_t *b, s16 **pcm, int jump)
tmp += *f++ * *v--; tmp += *f++ * *v--;
tmp += *f++ * *v--; tmp += *f++ * *v--;
tmp += *f++ * *v--; tmp += *f++ * *v--;
if((tmp += *f++ * *v) > 32767) if ((tmp += *f++ * *v) > 32767)
**pcm = 0x7FFF; **pcm = 0x7FFF;
else else
if(tmp < -32768) if (tmp < -32768)
**pcm = 0x8000; **pcm = 0x8000;
else else
**pcm = (s16)tmp; **pcm = (s16)tmp;
...@@ -630,7 +608,7 @@ void PCM(adec_bank_t *b, s16 **pcm, int jump) ...@@ -630,7 +608,7 @@ void PCM(adec_bank_t *b, s16 **pcm, int jump)
break; break;
case 5: case 5:
v = b->actual + 5; v = b->actual + 5;
for(i=0; i<32; i++) { for (i=0; i<32; i++) {
tmp = *f++ * *v--; tmp = *f++ * *v--;
tmp += *f++ * *v--; tmp += *f++ * *v--;
tmp += *f++ * *v--; tmp += *f++ * *v--;
...@@ -647,10 +625,10 @@ void PCM(adec_bank_t *b, s16 **pcm, int jump) ...@@ -647,10 +625,10 @@ void PCM(adec_bank_t *b, s16 **pcm, int jump)
tmp += *f++ * *v--; tmp += *f++ * *v--;
tmp += *f++ * *v--; tmp += *f++ * *v--;
tmp += *f++ * *v--; tmp += *f++ * *v--;
if((tmp += *f++ * *v) > 32767) if ((tmp += *f++ * *v) > 32767)
**pcm = 0x7FFF; **pcm = 0x7FFF;
else else
if(tmp < -32768) if (tmp < -32768)
**pcm = 0x8000; **pcm = 0x8000;
else else
**pcm = (s16)tmp; **pcm = (s16)tmp;
...@@ -660,7 +638,7 @@ void PCM(adec_bank_t *b, s16 **pcm, int jump) ...@@ -660,7 +638,7 @@ void PCM(adec_bank_t *b, s16 **pcm, int jump)
break; break;
case 6: case 6:
v = b->actual + 6; v = b->actual + 6;
for(i=0; i<32; i++) { for (i=0; i<32; i++) {
tmp = *f++ * *v--; tmp = *f++ * *v--;
tmp += *f++ * *v--; tmp += *f++ * *v--;
tmp += *f++ * *v--; tmp += *f++ * *v--;
...@@ -677,10 +655,10 @@ void PCM(adec_bank_t *b, s16 **pcm, int jump) ...@@ -677,10 +655,10 @@ void PCM(adec_bank_t *b, s16 **pcm, int jump)
tmp += *f++ * *v--; tmp += *f++ * *v--;
tmp += *f++ * *v--; tmp += *f++ * *v--;
tmp += *f++ * *v--; tmp += *f++ * *v--;
if((tmp += *f++ * *v) > 32767) if ((tmp += *f++ * *v) > 32767)
**pcm = 0x7FFF; **pcm = 0x7FFF;
else else
if(tmp < -32768) if (tmp < -32768)
**pcm = 0x8000; **pcm = 0x8000;
else else
**pcm = (s16)tmp; **pcm = (s16)tmp;
...@@ -690,7 +668,7 @@ void PCM(adec_bank_t *b, s16 **pcm, int jump) ...@@ -690,7 +668,7 @@ void PCM(adec_bank_t *b, s16 **pcm, int jump)
break; break;
case 7: case 7:
v = b->actual + 7; v = b->actual + 7;
for(i=0; i<32; i++) { for (i=0; i<32; i++) {
tmp = *f++ * *v--; tmp = *f++ * *v--;
tmp += *f++ * *v--; tmp += *f++ * *v--;
tmp += *f++ * *v--; tmp += *f++ * *v--;
...@@ -707,10 +685,10 @@ void PCM(adec_bank_t *b, s16 **pcm, int jump) ...@@ -707,10 +685,10 @@ void PCM(adec_bank_t *b, s16 **pcm, int jump)
tmp += *f++ * *v--; tmp += *f++ * *v--;
tmp += *f++ * *v--; tmp += *f++ * *v--;
tmp += *f++ * *v--; tmp += *f++ * *v--;
if((tmp += *f++ * *v) > 32767) if ((tmp += *f++ * *v) > 32767)
**pcm = 0x7FFF; **pcm = 0x7FFF;
else else
if(tmp < -32768) if (tmp < -32768)
**pcm = 0x8000; **pcm = 0x8000;
else else
**pcm = (s16)tmp; **pcm = (s16)tmp;
...@@ -720,7 +698,7 @@ void PCM(adec_bank_t *b, s16 **pcm, int jump) ...@@ -720,7 +698,7 @@ void PCM(adec_bank_t *b, s16 **pcm, int jump)
break; break;
case 8: case 8:
v = b->actual + 8; v = b->actual + 8;
for(i=0; i<32; i++) { for (i=0; i<32; i++) {
tmp = *f++ * *v--; tmp = *f++ * *v--;
tmp += *f++ * *v--; tmp += *f++ * *v--;
tmp += *f++ * *v--; tmp += *f++ * *v--;
...@@ -737,10 +715,10 @@ void PCM(adec_bank_t *b, s16 **pcm, int jump) ...@@ -737,10 +715,10 @@ void PCM(adec_bank_t *b, s16 **pcm, int jump)
tmp += *f++ * *v--; tmp += *f++ * *v--;
tmp += *f++ * *v--; tmp += *f++ * *v--;
tmp += *f++ * *v--; tmp += *f++ * *v--;
if((tmp += *f++ * *v) > 32767) if ((tmp += *f++ * *v) > 32767)
**pcm = 0x7FFF; **pcm = 0x7FFF;
else else
if(tmp < -32768) if (tmp < -32768)
**pcm = 0x8000; **pcm = 0x8000;
else else
**pcm = (s16)tmp; **pcm = (s16)tmp;
...@@ -750,7 +728,7 @@ void PCM(adec_bank_t *b, s16 **pcm, int jump) ...@@ -750,7 +728,7 @@ void PCM(adec_bank_t *b, s16 **pcm, int jump)
break; break;
case 9: case 9:
v = b->actual + 9; v = b->actual + 9;
for(i=0; i<32; i++) { for (i=0; i<32; i++) {
tmp = *f++ * *v--; tmp = *f++ * *v--;
tmp += *f++ * *v--; tmp += *f++ * *v--;
tmp += *f++ * *v--; tmp += *f++ * *v--;
...@@ -767,10 +745,10 @@ void PCM(adec_bank_t *b, s16 **pcm, int jump) ...@@ -767,10 +745,10 @@ void PCM(adec_bank_t *b, s16 **pcm, int jump)
tmp += *f++ * *v--; tmp += *f++ * *v--;
tmp += *f++ * *v--; tmp += *f++ * *v--;
tmp += *f++ * *v--; tmp += *f++ * *v--;
if((tmp += *f++ * *v) > 32767) if ((tmp += *f++ * *v) > 32767)
**pcm = 0x7FFF; **pcm = 0x7FFF;
else else
if(tmp < -32768) if (tmp < -32768)
**pcm = 0x8000; **pcm = 0x8000;
else else
**pcm = (s16)tmp; **pcm = (s16)tmp;
...@@ -780,7 +758,7 @@ void PCM(adec_bank_t *b, s16 **pcm, int jump) ...@@ -780,7 +758,7 @@ void PCM(adec_bank_t *b, s16 **pcm, int jump)
break; break;
case 10: case 10:
v = b->actual + 10; v = b->actual + 10;
for(i=0; i<32; i++) { for (i=0; i<32; i++) {
tmp = *f++ * *v--; tmp = *f++ * *v--;
tmp += *f++ * *v--; tmp += *f++ * *v--;
tmp += *f++ * *v--; tmp += *f++ * *v--;
...@@ -797,10 +775,10 @@ void PCM(adec_bank_t *b, s16 **pcm, int jump) ...@@ -797,10 +775,10 @@ void PCM(adec_bank_t *b, s16 **pcm, int jump)
tmp += *f++ * *v--; tmp += *f++ * *v--;
tmp += *f++ * *v--; tmp += *f++ * *v--;
tmp += *f++ * *v--; tmp += *f++ * *v--;
if((tmp += *f++ * *v) > 32767) if ((tmp += *f++ * *v) > 32767)
**pcm = 0x7FFF; **pcm = 0x7FFF;
else else
if(tmp < -32768) if (tmp < -32768)
**pcm = 0x8000; **pcm = 0x8000;
else else
**pcm = (s16)tmp; **pcm = (s16)tmp;
...@@ -810,7 +788,7 @@ void PCM(adec_bank_t *b, s16 **pcm, int jump) ...@@ -810,7 +788,7 @@ void PCM(adec_bank_t *b, s16 **pcm, int jump)
break; break;
case 11: case 11:
v = b->actual + 11; v = b->actual + 11;
for(i=0; i<32; i++) { for (i=0; i<32; i++) {
tmp = *f++ * *v--; tmp = *f++ * *v--;
tmp += *f++ * *v--; tmp += *f++ * *v--;
tmp += *f++ * *v--; tmp += *f++ * *v--;
...@@ -827,10 +805,10 @@ void PCM(adec_bank_t *b, s16 **pcm, int jump) ...@@ -827,10 +805,10 @@ void PCM(adec_bank_t *b, s16 **pcm, int jump)
tmp += *f++ * *v--; tmp += *f++ * *v--;
tmp += *f++ * *v--; tmp += *f++ * *v--;
tmp += *f++ * *v--; tmp += *f++ * *v--;
if((tmp += *f++ * *v) > 32767) if ((tmp += *f++ * *v) > 32767)
**pcm = 0x7FFF; **pcm = 0x7FFF;
else else
if(tmp < -32768) if (tmp < -32768)
**pcm = 0x8000; **pcm = 0x8000;
else else
**pcm = (s16)tmp; **pcm = (s16)tmp;
...@@ -840,7 +818,7 @@ void PCM(adec_bank_t *b, s16 **pcm, int jump) ...@@ -840,7 +818,7 @@ void PCM(adec_bank_t *b, s16 **pcm, int jump)
break; break;
case 12: case 12:
v = b->actual + 12; v = b->actual + 12;
for(i=0; i<32; i++) { for (i=0; i<32; i++) {
tmp = *f++ * *v--; tmp = *f++ * *v--;
tmp += *f++ * *v--; tmp += *f++ * *v--;
tmp += *f++ * *v--; tmp += *f++ * *v--;
...@@ -857,10 +835,10 @@ void PCM(adec_bank_t *b, s16 **pcm, int jump) ...@@ -857,10 +835,10 @@ void PCM(adec_bank_t *b, s16 **pcm, int jump)
v += 15; v += 15;
tmp += *f++ * *v--; tmp += *f++ * *v--;
tmp += *f++ * *v--; tmp += *f++ * *v--;
if((tmp += *f++ * *v) > 32767) if ((tmp += *f++ * *v) > 32767)
**pcm = 0x7FFF; **pcm = 0x7FFF;
else else
if(tmp < -32768) if (tmp < -32768)
**pcm = 0x8000; **pcm = 0x8000;
else else
**pcm = (s16)tmp; **pcm = (s16)tmp;
...@@ -870,7 +848,7 @@ void PCM(adec_bank_t *b, s16 **pcm, int jump) ...@@ -870,7 +848,7 @@ void PCM(adec_bank_t *b, s16 **pcm, int jump)
break; break;
case 13: case 13:
v = b->actual + 13; v = b->actual + 13;
for(i=0; i<32; i++) { for (i=0; i<32; i++) {
tmp = *f++ * *v--; tmp = *f++ * *v--;
tmp += *f++ * *v--; tmp += *f++ * *v--;
tmp += *f++ * *v--; tmp += *f++ * *v--;
...@@ -887,10 +865,10 @@ void PCM(adec_bank_t *b, s16 **pcm, int jump) ...@@ -887,10 +865,10 @@ void PCM(adec_bank_t *b, s16 **pcm, int jump)
tmp += *f++ * *v; tmp += *f++ * *v;
v += 15; v += 15;
tmp += *f++ * *v--; tmp += *f++ * *v--;
if((tmp += *f++ * *v) > 32767) if ((tmp += *f++ * *v) > 32767)
**pcm = 0x7FFF; **pcm = 0x7FFF;
else else
if(tmp < -32768) if (tmp < -32768)
**pcm = 0x8000; **pcm = 0x8000;
else else
**pcm = (s16)tmp; **pcm = (s16)tmp;
...@@ -900,7 +878,7 @@ void PCM(adec_bank_t *b, s16 **pcm, int jump) ...@@ -900,7 +878,7 @@ void PCM(adec_bank_t *b, s16 **pcm, int jump)
break; break;
case 14: case 14:
v = b->actual + 14; v = b->actual + 14;
for(i=0; i<32; i++) { for (i=0; i<32; i++) {
tmp = *f++ * *v--; tmp = *f++ * *v--;
tmp += *f++ * *v--; tmp += *f++ * *v--;
tmp += *f++ * *v--; tmp += *f++ * *v--;
...@@ -917,10 +895,10 @@ void PCM(adec_bank_t *b, s16 **pcm, int jump) ...@@ -917,10 +895,10 @@ void PCM(adec_bank_t *b, s16 **pcm, int jump)
tmp += *f++ * *v--; tmp += *f++ * *v--;
tmp += *f++ * *v; tmp += *f++ * *v;
v += 15; v += 15;
if((tmp += *f++ * *v) > 32767) if ((tmp += *f++ * *v) > 32767)
**pcm = 0x7FFF; **pcm = 0x7FFF;
else else
if(tmp < -32768) if (tmp < -32768)
**pcm = 0x8000; **pcm = 0x8000;
else else
**pcm = (s16)tmp; **pcm = (s16)tmp;
...@@ -930,7 +908,7 @@ void PCM(adec_bank_t *b, s16 **pcm, int jump) ...@@ -930,7 +908,7 @@ void PCM(adec_bank_t *b, s16 **pcm, int jump)
break; break;
case 15: case 15:
v = b->actual + 15; v = b->actual + 15;
for(i=0; i<32; i++) { for (i=0; i<32; i++) {
tmp = *f++ * *v--; tmp = *f++ * *v--;
tmp += *f++ * *v--; tmp += *f++ * *v--;
tmp += *f++ * *v--; tmp += *f++ * *v--;
...@@ -946,10 +924,10 @@ void PCM(adec_bank_t *b, s16 **pcm, int jump) ...@@ -946,10 +924,10 @@ void PCM(adec_bank_t *b, s16 **pcm, int jump)
tmp += *f++ * *v--; tmp += *f++ * *v--;
tmp += *f++ * *v--; tmp += *f++ * *v--;
tmp += *f++ * *v--; tmp += *f++ * *v--;
if((tmp += *f++ * *v) > 32767) if ((tmp += *f++ * *v) > 32767)
**pcm = 0x7FFF; **pcm = 0x7FFF;
else else
if(tmp < -32768) if (tmp < -32768)
**pcm = 0x8000; **pcm = 0x8000;
else else
**pcm = (s16)tmp; **pcm = (s16)tmp;
......
...@@ -54,7 +54,8 @@ ...@@ -54,7 +54,8 @@
#include "audio_output.h" /* aout_thread_t */ #include "audio_output.h" /* aout_thread_t */
#include "audio_decoder.h" /* adec_thread_t */ #include "audio_decoder.h" /* audiodec_t (for audio_decoder_thread.h) */
#include "audio_decoder_thread.h" /* adec_thread_t */
#include "ac3_decoder.h" /* ac3dec_t (for ac3_decoder_thread.h) */ #include "ac3_decoder.h" /* ac3dec_t (for ac3_decoder_thread.h) */
#include "ac3_decoder_thread.h" /* ac3dec_thread_t */ #include "ac3_decoder_thread.h" /* ac3dec_thread_t */
......
...@@ -47,7 +47,8 @@ ...@@ -47,7 +47,8 @@
#include "audio_output.h" /* aout_thread_t */ #include "audio_output.h" /* aout_thread_t */
#include "audio_decoder.h" /* adec_thread_t */ #include "audio_decoder.h" /* audiodec_t (for audio_decoder_thread.h) */
#include "audio_decoder_thread.h" /* adec_thread_t */
#include "ac3_decoder.h" /* ac3dec_t (for ac3_decoder_thread.h) */ #include "ac3_decoder.h" /* ac3dec_t (for ac3_decoder_thread.h) */
#include "ac3_decoder_thread.h" /* ac3dec_thread_t */ #include "ac3_decoder_thread.h" /* ac3dec_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