mirror of
https://github.com/videolan/vlc.git
synced 2024-12-03 23:04:35 +08:00
All decoders (audio, video, subtitles) are now modules.
- mpeg_vdec, mpeg_adec and ac3_adec are builtins by default - ac3_spdif, spu_dec and lpcm_dec are plugins by default
This commit is contained in:
parent
bee557f980
commit
49a0736e1c
4
AUTHORS
4
AUTHORS
@ -83,8 +83,8 @@ N: Henri Fallon
|
||||
E: henri@via.ecp.fr
|
||||
C: henri
|
||||
D: ALSA audio output
|
||||
D: input netlist
|
||||
D: MPEG TS input
|
||||
D: MPEG TS input, input netlist.
|
||||
D: Decoder modularization
|
||||
|
||||
N: Arnaud Gomes-do-Vale
|
||||
E: arnaud@carrosse.frmug.org
|
||||
|
32
Makefile
32
Makefile
@ -13,7 +13,9 @@ endif
|
||||
#
|
||||
# All possible plugin directories, needed for make clean
|
||||
#
|
||||
PLUGINS_DIR := alsa \
|
||||
PLUGINS_DIR := ac3_adec \
|
||||
ac3_spdif \
|
||||
alsa \
|
||||
beos \
|
||||
darwin \
|
||||
directx \
|
||||
@ -29,21 +31,24 @@ PLUGINS_DIR := alsa \
|
||||
idct \
|
||||
imdct \
|
||||
kde \
|
||||
lpcm_adec \
|
||||
macosx \
|
||||
mga \
|
||||
motion \
|
||||
mpeg \
|
||||
mpeg_adec \
|
||||
mpeg_vdec \
|
||||
qt \
|
||||
sdl \
|
||||
spu_dec \
|
||||
text \
|
||||
vcd \
|
||||
x11 \
|
||||
yuv
|
||||
|
||||
#
|
||||
# All possible plugin objects
|
||||
#
|
||||
PLUGINS_TARGETS := alsa/alsa \
|
||||
PLUGINS_TARGETS := ac3_adec/ac3_adec \
|
||||
ac3_spdif/ac3_spdif \
|
||||
alsa/alsa \
|
||||
beos/beos \
|
||||
darwin/darwin \
|
||||
directx/directx \
|
||||
@ -69,6 +74,7 @@ PLUGINS_TARGETS := alsa/alsa \
|
||||
imdct/imdct3dn \
|
||||
imdct/imdctsse \
|
||||
kde/kde \
|
||||
lpcm_adec/lpcm_adec \
|
||||
macosx/macosx \
|
||||
macosx/macosx_qt \
|
||||
mga/mga \
|
||||
@ -77,11 +83,14 @@ PLUGINS_TARGETS := alsa/alsa \
|
||||
motion/motionmmxext \
|
||||
motion/motion3dnow \
|
||||
motion/motionaltivec \
|
||||
mpeg_adec/mpeg_adec \
|
||||
mpeg_vdec/mpeg_vdec \
|
||||
mpeg/es \
|
||||
mpeg/ps \
|
||||
mpeg/ts \
|
||||
qt/qt \
|
||||
sdl/sdl \
|
||||
spu_dec/spu_dec \
|
||||
text/ncurses \
|
||||
text/rc \
|
||||
vcd/vcd \
|
||||
@ -89,7 +98,6 @@ PLUGINS_TARGETS := alsa/alsa \
|
||||
x11/xvideo \
|
||||
yuv/yuv \
|
||||
yuv/yuvmmx
|
||||
|
||||
#
|
||||
# C Objects
|
||||
#
|
||||
@ -97,24 +105,12 @@ INTERFACE := main interface intf_msg intf_playlist intf_channels
|
||||
INPUT := input input_ext-dec input_ext-intf input_dec input_programs input_netlist input_clock mpeg_system
|
||||
VIDEO_OUTPUT := video_output video_text video_spu video_yuv
|
||||
AUDIO_OUTPUT := audio_output aout_ext-dec aout_u8 aout_s8 aout_u16 aout_s16 aout_spdif
|
||||
AC3_DECODER := ac3_decoder_thread ac3_decoder ac3_parse ac3_exponent ac3_bit_allocate ac3_mantissa ac3_rematrix ac3_imdct
|
||||
AC3_SPDIF := ac3_spdif ac3_iec958
|
||||
LPCM_DECODER := lpcm_decoder_thread
|
||||
AUDIO_DECODER := audio_decoder adec_generic adec_layer1 adec_layer2 adec_math
|
||||
SPU_DECODER := spu_decoder
|
||||
VIDEO_DECODER := video_parser vpar_headers vpar_blocks vpar_synchro vpar_pool video_decoder
|
||||
MISC := mtime tests modules netutils iso_lang
|
||||
|
||||
C_OBJ := $(INTERFACE:%=src/interface/%.o) \
|
||||
$(INPUT:%=src/input/%.o) \
|
||||
$(VIDEO_OUTPUT:%=src/video_output/%.o) \
|
||||
$(AUDIO_OUTPUT:%=src/audio_output/%.o) \
|
||||
$(AC3_DECODER:%=src/ac3_decoder/%.o) \
|
||||
$(AC3_SPDIF:%=src/ac3_spdif/%.o) \
|
||||
$(LPCM_DECODER:%=src/lpcm_decoder/%.o) \
|
||||
$(AUDIO_DECODER:%=src/audio_decoder/%.o) \
|
||||
$(SPU_DECODER:%=src/spu_decoder/%.o) \
|
||||
$(VIDEO_DECODER:%=src/video_decoder/%.o) \
|
||||
$(MISC:%=src/misc/%.o)
|
||||
|
||||
#
|
||||
|
2
TODO
2
TODO
@ -198,7 +198,7 @@ Task: 0x47
|
||||
Difficulty: Hard
|
||||
Urgency: Normal
|
||||
Description: Make decoders dynamically loadable
|
||||
Status: Todo
|
||||
Status: Done 05 October 2001 (henri)
|
||||
|
||||
Task: 0x46
|
||||
Difficulty: Hard
|
||||
|
4
configure
vendored
4
configure
vendored
@ -3699,8 +3699,8 @@ fi
|
||||
|
||||
ARCH=${target_cpu}
|
||||
|
||||
BUILTINS="${BUILTINS} es ps ts yuv idct idctclassic motion imdct downmix"
|
||||
PLUGINS="${PLUGINS}"
|
||||
BUILTINS="${BUILTINS} es ps ts yuv idct idctclassic motion imdct downmix mpeg_adec lpcm_adec ac3_adec mpeg_vdec"
|
||||
PLUGINS="${PLUGINS} ac3_spdif spu_dec"
|
||||
|
||||
MMX_MODULES="yuvmmx idctmmx motionmmx"
|
||||
MMXEXT_MODULES="idctmmxext motionmmxext"
|
||||
|
@ -295,8 +295,8 @@ ARCH=${target_cpu}
|
||||
dnl
|
||||
dnl default modules
|
||||
dnl
|
||||
BUILTINS="${BUILTINS} es ps ts yuv idct idctclassic motion imdct downmix"
|
||||
PLUGINS="${PLUGINS}"
|
||||
BUILTINS="${BUILTINS} es ps ts yuv idct idctclassic motion imdct downmix mpeg_adec lpcm_adec ac3_adec mpeg_vdec"
|
||||
PLUGINS="${PLUGINS} ac3_spdif spu_dec"
|
||||
|
||||
dnl
|
||||
dnl Accelerated modules
|
||||
|
@ -23,20 +23,20 @@ chapters.
|
||||
<sect1> <title> Decoder configuration </title>
|
||||
|
||||
<para>
|
||||
The input thread spawns the appropriate decoders [the relation is
|
||||
currently hard-wired in <filename>src/input/input_programs.c</filename>].
|
||||
It then launches <function> *_CreateThread()</function>, with either
|
||||
an <type>adec_config_t</type> (audio) or an <type> vdec_config_t</type>
|
||||
(video) structure, described in <filename> include/input_ext-dec.h</filename>.
|
||||
The input thread spawns the appropriate decoder modules from <filename>
|
||||
src/input/input_dec.c</filename>. The <function>Dec_CreateThread</funcion>
|
||||
function selects the more accurate decoder module. Each decoder module
|
||||
looks at decoder_config.i_type and returns a score [ see the modules
|
||||
section ]. It then launches <function> module.pf_RunThread()</function>,
|
||||
with an <type>decoder_config_t</type> (audio) or an <type> vdec_config_t
|
||||
</type>, described in <filename> include/input_ext-dec.h</filename>.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
It contains some parameters relative to the output thread, which will
|
||||
be described in the following chapters, and a generic <type>
|
||||
decoder_config_t</type>, which gives the decoder the ES ID and type, and
|
||||
pointers to a <type> stream_control_t </type> structure (gives
|
||||
information on the play status), a <type> decoder_fifo_t </type>
|
||||
and <parameter> pf_init_bit_stream</parameter>, which will be
|
||||
The generic <type>decoder_config_t</type> structure, gives the decoder
|
||||
the ES ID and type, and pointers to a <type> stream_control_t </type>
|
||||
structure (gives information on the play status), a <type> decoder_fifo_t
|
||||
</type> and <parameter> pf_init_bit_stream</parameter>, which will be
|
||||
described in the next two sections.
|
||||
</para>
|
||||
|
||||
@ -379,7 +379,8 @@ seven methods :
|
||||
|
||||
<itemizedlist>
|
||||
<listitem> <para> <function> vdec_IDCT </function> <parameter>
|
||||
( vdec_thread_t * p_vdec, dctelem_t * p_block, int ) </parameter> :
|
||||
( decoder_config_t * p_config, dctelem_t * p_block, int )
|
||||
</parameter> :
|
||||
Does the complete 2-D IDCT. 64 coefficients are in <parameter>
|
||||
p_block</parameter>.
|
||||
</para> </listitem>
|
||||
|
@ -49,8 +49,15 @@
|
||||
S.A.S. </ulink> </orgname>
|
||||
</affiliation>
|
||||
</collab>
|
||||
|
||||
<pubdate> $Id: manual.xml,v 1.1 2001/07/16 15:54:59 massiot Exp $ </pubdate>
|
||||
<collab>
|
||||
<collabname> <ulink url="mailto:henri@via.ecp.fr">Henri Fallon
|
||||
</ulink> </collabname>
|
||||
<affiliation>
|
||||
<jobtitle> Developer </jobtitle>
|
||||
<orgname> VideoLAN project </orgname>
|
||||
</affiliation>
|
||||
</collab>
|
||||
<pubdate> $Id: manual.xml,v 1.2 2001/11/13 12:09:17 henri Exp $ </pubdate>
|
||||
<copyright> <year> 2001 </year>
|
||||
<holder> Christophe Massiot, for IDEALX S.A.S. </holder>
|
||||
</copyright>
|
||||
|
@ -3,7 +3,7 @@
|
||||
* Collection of useful common types and macros definitions
|
||||
*****************************************************************************
|
||||
* Copyright (C) 1998, 1999, 2000 VideoLAN
|
||||
* $Id: common.h,v 1.47 2001/11/08 21:07:24 jlj Exp $
|
||||
* $Id: common.h,v 1.48 2001/11/13 12:09:17 henri Exp $
|
||||
*
|
||||
* Authors: Samuel Hocevar <sam@via.ecp.fr>
|
||||
* Vincent Seguin <seguin@via.ecp.fr>
|
||||
@ -85,6 +85,7 @@ typedef struct plugin_info_s * p_plugin_info_t;
|
||||
/* Plugins */
|
||||
struct playlist_s;
|
||||
struct playlist_item_s;
|
||||
struct module_s;
|
||||
|
||||
typedef struct playlist_s * p_playlist_t;
|
||||
typedef struct playlist_item_s * p_playlist_item_t;
|
||||
@ -125,6 +126,7 @@ struct vout_sys_s;
|
||||
struct vdec_thread_s;
|
||||
struct vpar_thread_s;
|
||||
struct video_parser_s;
|
||||
struct picture_t;
|
||||
|
||||
typedef struct vout_thread_s * p_vout_thread_t;
|
||||
typedef struct vout_font_s * p_vout_font_t;
|
||||
@ -138,6 +140,13 @@ struct macroblock_s;
|
||||
struct data_packet_s;
|
||||
struct es_descriptor_s;
|
||||
struct pgrm_descriptor_s;
|
||||
struct pes_packet_s;
|
||||
struct input_area_s;
|
||||
struct bit_stream_s;
|
||||
|
||||
/* Decoders */
|
||||
struct decoder_config_s;
|
||||
struct decoder_fifo_s;
|
||||
|
||||
/*****************************************************************************
|
||||
* Macros and inline functions
|
||||
|
@ -2,7 +2,7 @@
|
||||
* input_ext-dec.h: structures exported to the VideoLAN decoders
|
||||
*****************************************************************************
|
||||
* Copyright (C) 1999, 2000 VideoLAN
|
||||
* $Id: input_ext-dec.h,v 1.36 2001/10/03 12:46:17 massiot Exp $
|
||||
* $Id: input_ext-dec.h,v 1.37 2001/11/13 12:09:17 henri Exp $
|
||||
*
|
||||
* Authors: Christophe Massiot <massiot@via.ecp.fr>
|
||||
* Michel Kaempf <maxx@via.ecp.fr>
|
||||
@ -22,6 +22,17 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
|
||||
*****************************************************************************/
|
||||
|
||||
/* ES streams types - see ISO/IEC 13818-1 table 2-29 numbers */
|
||||
#define MPEG1_VIDEO_ES 0x01
|
||||
#define MPEG2_VIDEO_ES 0x02
|
||||
#define MPEG1_AUDIO_ES 0x03
|
||||
#define MPEG2_AUDIO_ES 0x04
|
||||
#define AC3_AUDIO_ES 0x81
|
||||
/* These ones might violate the norm : */
|
||||
#define DVD_SPU_ES 0x82
|
||||
#define LPCM_AUDIO_ES 0x83
|
||||
#define UNKNOWN_ES 0xFF
|
||||
|
||||
/* Structures exported to the decoders */
|
||||
|
||||
/*****************************************************************************
|
||||
@ -203,9 +214,11 @@ typedef struct bit_stream_s
|
||||
/*****************************************************************************
|
||||
* Protoypes from input_ext-dec.c
|
||||
*****************************************************************************/
|
||||
#ifndef PLUGIN
|
||||
u32 UnalignedShowBits( struct bit_stream_s *, unsigned int );
|
||||
void UnalignedRemoveBits( struct bit_stream_s * );
|
||||
u32 UnalignedGetBits( struct bit_stream_s *, unsigned int );
|
||||
#endif
|
||||
|
||||
/*****************************************************************************
|
||||
* AlignWord : fill in the bit buffer so that the byte pointer be aligned
|
||||
@ -517,54 +530,14 @@ typedef struct decoder_config_s
|
||||
void (* pf_bitstream_callback)( struct bit_stream_s *,
|
||||
boolean_t ),
|
||||
void * );
|
||||
/* Decoder thread */
|
||||
vlc_thread_t thread_id;
|
||||
|
||||
/* Plugin/Builtin properties */
|
||||
struct module_s * p_dec_module;
|
||||
|
||||
} decoder_config_t;
|
||||
|
||||
/*****************************************************************************
|
||||
* vdec_config_t
|
||||
*****************************************************************************
|
||||
* Pointers given to video decoders threads.
|
||||
*****************************************************************************/
|
||||
struct vout_thread_s;
|
||||
|
||||
typedef struct vdec_config_s
|
||||
{
|
||||
struct picture_s * (* pf_create_picture)( struct vout_thread_s *,
|
||||
int i_type, int i_width,
|
||||
int i_height );
|
||||
void (* pf_destroy_picture)( struct vout_thread_s *,
|
||||
struct picture_s * );
|
||||
void (* pf_display_picture)( struct vout_thread_s *,
|
||||
struct picture_s * );
|
||||
void (* pf_date_picture)( struct vout_thread_s *,
|
||||
struct picture_s *, mtime_t date );
|
||||
void (* pf_link_picture)( struct vout_thread_s *,
|
||||
struct picture_s *, mtime_t date );
|
||||
void (* pf_unlink_picture)( struct vout_thread_s *,
|
||||
struct picture_s *, mtime_t date );
|
||||
struct subpicture_s *(* pf_create_subpicture)( struct vout_thread_s *,
|
||||
int i_type, int i_size );
|
||||
void (* pf_destroy_subpicture)( struct vout_thread_s *,
|
||||
struct subpicture_s * );
|
||||
void (* pf_display_subpicture)( struct vout_thread_s *,
|
||||
struct subpicture_s * );
|
||||
|
||||
decoder_config_t decoder_config;
|
||||
} vdec_config_t;
|
||||
|
||||
/*****************************************************************************
|
||||
* adec_config_t
|
||||
*****************************************************************************
|
||||
* Pointers given to audio decoders threads.
|
||||
*****************************************************************************/
|
||||
typedef struct adec_config_s
|
||||
{
|
||||
struct aout_fifo_s * (* pf_create_fifo)( struct aout_fifo_s * );
|
||||
void (* pf_destroy_fifo)( void );
|
||||
|
||||
decoder_config_t decoder_config;
|
||||
} adec_config_t;
|
||||
|
||||
|
||||
/*
|
||||
* Communication interface between decoders and input
|
||||
*/
|
||||
|
@ -4,7 +4,7 @@
|
||||
* control the pace of reading.
|
||||
*****************************************************************************
|
||||
* Copyright (C) 1999, 2000 VideoLAN
|
||||
* $Id: input_ext-intf.h,v 1.46 2001/11/11 18:15:41 sam Exp $
|
||||
* $Id: input_ext-intf.h,v 1.47 2001/11/13 12:09:17 henri Exp $
|
||||
*
|
||||
* Authors: Christophe Massiot <massiot@via.ecp.fr>
|
||||
*
|
||||
@ -75,6 +75,8 @@ typedef struct es_descriptor_s
|
||||
|
||||
count_t c_packets; /* total packets read */
|
||||
count_t c_invalid_packets; /* invalid packets read */
|
||||
|
||||
struct decoder_config_s * p_dec_config;
|
||||
} es_descriptor_t;
|
||||
|
||||
/* Special PID values - note that the PID is only on 13 bits, and that values
|
||||
@ -83,16 +85,6 @@ typedef struct es_descriptor_s
|
||||
#define CONDITIONNAL_ACCESS_TABLE_PID 0x0001 /* not used */
|
||||
#define EMPTY_ID 0xffff /* empty record in a table */
|
||||
|
||||
/* ES streams types - see ISO/IEC 13818-1 table 2-29 numbers */
|
||||
#define MPEG1_VIDEO_ES 0x01
|
||||
#define MPEG2_VIDEO_ES 0x02
|
||||
#define MPEG1_AUDIO_ES 0x03
|
||||
#define MPEG2_AUDIO_ES 0x04
|
||||
#define AC3_AUDIO_ES 0x81
|
||||
/* These ones might violate the norm : */
|
||||
#define DVD_SPU_ES 0x82
|
||||
#define LPCM_AUDIO_ES 0x83
|
||||
#define UNKNOWN_ES 0xFF
|
||||
|
||||
/* ES Categories to be used by interface plugins */
|
||||
#define VIDEO_ES 0x00
|
||||
|
@ -3,7 +3,7 @@
|
||||
* but exported to plug-ins
|
||||
*****************************************************************************
|
||||
* Copyright (C) 1999, 2000, 2001 VideoLAN
|
||||
* $Id: input_ext-plugins.h,v 1.3 2001/11/11 01:32:03 stef Exp $
|
||||
* $Id: input_ext-plugins.h,v 1.4 2001/11/13 12:09:17 henri Exp $
|
||||
*
|
||||
* Authors: Christophe Massiot <massiot@via.ecp.fr>
|
||||
*
|
||||
@ -69,7 +69,7 @@ int input_UnselectES( struct input_thread_s *, struct es_descriptor_s * );
|
||||
* Prototypes from input_dec.c
|
||||
*****************************************************************************/
|
||||
//decoder_capabilities_s * input_ProbeDecoder( void );
|
||||
vlc_thread_t input_RunDecoder( struct decoder_capabilities_s *, void * );
|
||||
vlc_thread_t input_RunDecoder( void * );
|
||||
void input_EndDecoder( struct input_thread_s *, struct es_descriptor_s * );
|
||||
void input_DecodePES ( struct decoder_fifo_s *, struct pes_packet_s * );
|
||||
void input_EscapeDiscontinuity( struct input_thread_s *,
|
||||
|
@ -2,7 +2,7 @@
|
||||
* modules.h : Module management functions.
|
||||
*****************************************************************************
|
||||
* Copyright (C) 2001 VideoLAN
|
||||
* $Id: modules.h,v 1.30 2001/11/08 01:48:09 jlj Exp $
|
||||
* $Id: modules.h,v 1.31 2001/11/13 12:09:17 henri Exp $
|
||||
*
|
||||
* Authors: Samuel Hocevar <sam@zoy.org>
|
||||
*
|
||||
@ -59,15 +59,14 @@ typedef void * module_handle_t;
|
||||
#define MODULE_CAPABILITY_ACCESS 1 << 1 /* Input */
|
||||
#define MODULE_CAPABILITY_INPUT 1 << 2 /* Input */
|
||||
#define MODULE_CAPABILITY_DECAPS 1 << 3 /* Decaps */
|
||||
#define MODULE_CAPABILITY_ADEC 1 << 4 /* Audio decoder */
|
||||
#define MODULE_CAPABILITY_VDEC 1 << 5 /* Video decoder */
|
||||
#define MODULE_CAPABILITY_MOTION 1 << 6 /* Motion compensation */
|
||||
#define MODULE_CAPABILITY_IDCT 1 << 7 /* IDCT transformation */
|
||||
#define MODULE_CAPABILITY_AOUT 1 << 8 /* Audio output */
|
||||
#define MODULE_CAPABILITY_VOUT 1 << 9 /* Video output */
|
||||
#define MODULE_CAPABILITY_YUV 1 << 10 /* YUV colorspace conversion */
|
||||
#define MODULE_CAPABILITY_IMDCT 1 << 11 /* IMDCT transformation */
|
||||
#define MODULE_CAPABILITY_DOWNMIX 1 << 12 /* AC3 downmix */
|
||||
#define MODULE_CAPABILITY_DEC 1 << 4 /* Video decoder */
|
||||
#define MODULE_CAPABILITY_MOTION 1 << 5 /* Motion compensation */
|
||||
#define MODULE_CAPABILITY_IDCT 1 << 6 /* IDCT transformation */
|
||||
#define MODULE_CAPABILITY_AOUT 1 << 7 /* Audio output */
|
||||
#define MODULE_CAPABILITY_VOUT 1 << 8 /* Video output */
|
||||
#define MODULE_CAPABILITY_YUV 1 << 9 /* YUV colorspace conversion */
|
||||
#define MODULE_CAPABILITY_IMDCT 1 << 10 /* IMDCT transformation */
|
||||
#define MODULE_CAPABILITY_DOWNMIX 1 << 11 /* AC3 downmix */
|
||||
|
||||
/* FIXME: kludge */
|
||||
struct input_area_s;
|
||||
@ -77,9 +76,12 @@ struct dm_par_s;
|
||||
struct bit_stream_s;
|
||||
struct decoder_fifo_s;
|
||||
|
||||
struct decoder_config_s;
|
||||
|
||||
/* FIXME: not yet used */
|
||||
typedef struct probedata_s
|
||||
{
|
||||
u8 i_type;
|
||||
struct
|
||||
{
|
||||
char * psz_data;
|
||||
@ -214,6 +216,12 @@ typedef struct function_list_s
|
||||
|
||||
} downmix;
|
||||
|
||||
/* Decoder plugins */
|
||||
struct
|
||||
{
|
||||
int ( * pf_RunThread ) ( struct decoder_config_s * p_config );
|
||||
} dec;
|
||||
|
||||
} functions;
|
||||
|
||||
} function_list_t;
|
||||
@ -225,8 +233,7 @@ typedef struct module_functions_s
|
||||
function_list_t access;
|
||||
function_list_t input;
|
||||
function_list_t decaps;
|
||||
function_list_t adec;
|
||||
function_list_t vdec;
|
||||
function_list_t dec;
|
||||
function_list_t motion;
|
||||
function_list_t idct;
|
||||
function_list_t aout;
|
||||
|
@ -19,6 +19,7 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
|
||||
*****************************************************************************/
|
||||
struct module_t;
|
||||
|
||||
typedef struct module_symbols_s
|
||||
{
|
||||
@ -40,6 +41,7 @@ typedef struct module_symbols_s
|
||||
|
||||
void ( * intf_Msg ) ( char *, ... );
|
||||
void ( * intf_ErrMsg ) ( char *, ... );
|
||||
void ( * intf_StatMsg ) ( char *, ... );
|
||||
void ( * intf_WarnMsg ) ( int, char *, ... );
|
||||
void ( * intf_WarnMsgImm ) ( int, char *, ... );
|
||||
#ifdef TRACE
|
||||
@ -132,6 +134,38 @@ typedef struct module_symbols_s
|
||||
void ( * input_NetlistDeletePES ) ( void *, struct pes_packet_s * );
|
||||
void ( * input_NetlistEnd ) ( struct input_thread_s * );
|
||||
|
||||
struct aout_fifo_s * ( * aout_CreateFifo )
|
||||
( int, int, long, long, long, void * );
|
||||
void ( * aout_DestroyFifo ) ( struct aout_fifo_s * );
|
||||
|
||||
struct vout_thread_s * (* vout_CreateThread) ( int *, int, int );
|
||||
struct subpicture_s * (* vout_CreateSubPicture) ( struct vout_thread_s *,
|
||||
int, int );
|
||||
struct picture_s * ( * vout_CreatePicture ) ( struct vout_thread_s *,
|
||||
int, int, int );
|
||||
|
||||
void ( * vout_DestroySubPicture ) ( struct vout_thread_s *,
|
||||
struct subpicture_s * );
|
||||
void ( * vout_DisplaySubPicture ) ( struct vout_thread_s *,
|
||||
struct subpicture_s * );
|
||||
void ( * vout_DisplayPicture ) ( struct vout_thread_s *,
|
||||
struct picture_s * );
|
||||
void ( * vout_DestroyPicture ) ( struct vout_thread_s *,
|
||||
struct picture_s * );
|
||||
void ( * vout_LinkPicture ) ( struct vout_thread_s *,
|
||||
struct picture_s * );
|
||||
void ( * vout_UnlinkPicture ) ( struct vout_thread_s *,
|
||||
struct picture_s * );
|
||||
void ( * vout_DatePicture ) ( struct vout_thread_s *p_vout,
|
||||
struct picture_s *p_pic, mtime_t );
|
||||
|
||||
|
||||
u32 ( * UnalignedShowBits ) ( struct bit_stream_s *, unsigned int );
|
||||
void ( * UnalignedRemoveBits ) ( struct bit_stream_s * );
|
||||
u32 ( * UnalignedGetBits ) ( struct bit_stream_s *, unsigned int );
|
||||
|
||||
struct module_s * ( * module_Need ) ( int, void * );
|
||||
void ( * module_Unneed ) ( struct module_s * );
|
||||
} module_symbols_t;
|
||||
|
||||
#define STORE_SYMBOLS( p_symbols ) \
|
||||
@ -149,6 +183,7 @@ typedef struct module_symbols_s
|
||||
(p_symbols)->intf_ProcessKey = intf_ProcessKey; \
|
||||
(p_symbols)->intf_Msg = intf_Msg; \
|
||||
(p_symbols)->intf_ErrMsg = intf_ErrMsg; \
|
||||
(p_symbols)->intf_StatMsg = intf_StatMsg;\
|
||||
(p_symbols)->intf_WarnMsg = intf_WarnMsg; \
|
||||
(p_symbols)->intf_WarnMsgImm = intf_WarnMsgImm; \
|
||||
(p_symbols)->intf_PlaylistAdd = intf_PlaylistAdd; \
|
||||
@ -197,7 +232,24 @@ typedef struct module_symbols_s
|
||||
(p_symbols)->input_NetlistNewPES = input_NetlistNewPES; \
|
||||
(p_symbols)->input_NetlistDeletePacket = input_NetlistDeletePacket; \
|
||||
(p_symbols)->input_NetlistDeletePES = input_NetlistDeletePES; \
|
||||
(p_symbols)->input_NetlistEnd = input_NetlistEnd;
|
||||
(p_symbols)->input_NetlistEnd = input_NetlistEnd; \
|
||||
(p_symbols)->aout_CreateFifo = aout_CreateFifo; \
|
||||
(p_symbols)->aout_DestroyFifo = aout_DestroyFifo; \
|
||||
(p_symbols)->vout_CreateThread = vout_CreateThread; \
|
||||
(p_symbols)->vout_CreateSubPicture = vout_CreateSubPicture; \
|
||||
(p_symbols)->vout_DestroySubPicture = vout_DestroySubPicture; \
|
||||
(p_symbols)->vout_DisplaySubPicture = vout_DisplaySubPicture; \
|
||||
(p_symbols)->vout_CreatePicture = vout_CreatePicture; \
|
||||
(p_symbols)->vout_DisplayPicture = vout_DisplayPicture; \
|
||||
(p_symbols)->vout_DestroyPicture = vout_DestroyPicture; \
|
||||
(p_symbols)->vout_DatePicture = vout_DatePicture; \
|
||||
(p_symbols)->vout_LinkPicture = vout_LinkPicture; \
|
||||
(p_symbols)->vout_UnlinkPicture = vout_UnlinkPicture; \
|
||||
(p_symbols)->UnalignedGetBits = UnalignedGetBits; \
|
||||
(p_symbols)->UnalignedRemoveBits = UnalignedRemoveBits; \
|
||||
(p_symbols)->UnalignedShowBits = UnalignedShowBits; \
|
||||
(p_symbols)->module_Need = module_Need; \
|
||||
(p_symbols)->module_Unneed = module_Unneed;
|
||||
|
||||
#define STORE_TRACE_SYMBOLS( p_symbols ) \
|
||||
(p_symbols)->intf_DbgMsg = _intf_DbgMsg; \
|
||||
@ -224,6 +276,7 @@ extern module_symbols_t* p_symbols;
|
||||
|
||||
# define intf_Msg p_symbols->intf_Msg
|
||||
# define intf_ErrMsg p_symbols->intf_ErrMsg
|
||||
# define intf_StatMsg p_symbols->intf_StatMsg
|
||||
# define intf_WarnMsg p_symbols->intf_WarnMsg
|
||||
# define intf_WarnMsgImm p_symbols->intf_WarnMsgImm
|
||||
#ifdef TRACE
|
||||
@ -291,5 +344,25 @@ extern module_symbols_t* p_symbols;
|
||||
# define input_NetlistDeletePES p_symbols->input_NetlistDeletePES
|
||||
# define input_NetlistEnd p_symbols->input_NetlistEnd
|
||||
|
||||
# define aout_CreateFifo p_symbols->aout_CreateFifo
|
||||
# define aout_DestroyFifo p_symbols->aout_DestroyFifo
|
||||
|
||||
# define vout_CreateThread p_symbols->vout_CreateThread
|
||||
# define vout_CreateSubPicture p_symbols->vout_CreateSubPicture
|
||||
# define vout_DestroySubPicture p_symbols->vout_DestroySubPicture
|
||||
# define vout_DisplaySubPicture p_symbols->vout_DisplaySubPicture
|
||||
# define vout_CreatePicture p_symbols->vout_CreatePicture
|
||||
# define vout_DisplayPicture p_symbols->vout_DisplayPicture
|
||||
# define vout_DestroyPicture p_symbols->vout_DestroyPicture
|
||||
# define vout_DatePicture p_symbols->vout_DatePicture
|
||||
# define vout_LinkPicture p_symbols->vout_LinkPicture
|
||||
# define vout_UnlinkPicture p_symbols->vout_UnlinkPicture
|
||||
|
||||
# define UnalignedShowBits p_symbols->UnalignedShowBits
|
||||
# define UnalignedRemoveBits p_symbols->UnalignedRemoveBits
|
||||
# define UnalignedGetBits p_symbols->UnalignedGetBits
|
||||
# define module_Need p_symbols->module_Need
|
||||
# define module_Unneed p_symbols->module_Unneed
|
||||
|
||||
#endif
|
||||
|
||||
|
29
plugins/ac3_adec/Makefile
Normal file
29
plugins/ac3_adec/Makefile
Normal file
@ -0,0 +1,29 @@
|
||||
###############################################################################
|
||||
# vlc (VideoLAN Client) AC3 audio decoder module makefile
|
||||
# (c)2001 VideoLAN
|
||||
###############################################################################
|
||||
|
||||
#
|
||||
# Objects
|
||||
#
|
||||
PLUGIN_C = ac3_adec.o ac3_decoder.o ac3_parse.o ac3_exponent.o ac3_bit_allocate.o ac3_mantissa.o ac3_rematrix.o ac3_imdct.o
|
||||
BUILTIN_C = $(PLUGIN_C:%.o=BUILTIN_%.o)
|
||||
|
||||
ALL_OBJ = $(PLUGIN_C) $(BUILTIN_C)
|
||||
#
|
||||
# Virtual targets
|
||||
#
|
||||
|
||||
include ../../Makefile.modules
|
||||
|
||||
#
|
||||
# Real targets
|
||||
#
|
||||
|
||||
../ac3_adec.so: $(PLUGIN_C)
|
||||
$(CC) $(PCFLAGS) -o $@ $^ $(PLCFLAGS)
|
||||
|
||||
../ac3_adec.a: $(BUILTIN_C)
|
||||
ar r $@ $^
|
||||
$(RANLIB) $@
|
||||
|
@ -1,8 +1,8 @@
|
||||
/*****************************************************************************
|
||||
* ac3_decoder_thread.c: ac3 decoder thread
|
||||
* ac3_adec.c: ac3 decoder module main file
|
||||
*****************************************************************************
|
||||
* Copyright (C) 1999, 2000 VideoLAN
|
||||
* $Id: ac3_decoder_thread.c,v 1.39 2001/10/31 11:55:53 reno Exp $
|
||||
* $Id: ac3_adec.c,v 1.1 2001/11/13 12:09:17 henri Exp $
|
||||
*
|
||||
* Authors: Michel Lespinasse <walken@zoy.org>
|
||||
*
|
||||
@ -29,6 +29,8 @@
|
||||
* - vlc_cond_signal() / vlc_cond_wait()
|
||||
*
|
||||
*/
|
||||
#define MODULE_NAME ac3_adec
|
||||
#include "modules_inner.h"
|
||||
|
||||
/*****************************************************************************
|
||||
* Preamble
|
||||
@ -46,40 +48,88 @@
|
||||
#include "common.h"
|
||||
#include "threads.h"
|
||||
#include "mtime.h"
|
||||
#include "modules.h"
|
||||
|
||||
#include "intf_msg.h" /* intf_DbgMsg(), intf_ErrMsg() */
|
||||
|
||||
#include "audio_output.h"
|
||||
|
||||
#include "modules.h"
|
||||
#include "modules_export.h"
|
||||
|
||||
#include "stream_control.h"
|
||||
#include "input_ext-dec.h"
|
||||
|
||||
#include "audio_output.h"
|
||||
#include "input_ext-intf.h" /* MPEG?_AUDIO_ES */
|
||||
|
||||
#include "ac3_imdct.h"
|
||||
#include "ac3_downmix.h"
|
||||
#include "ac3_decoder.h"
|
||||
#include "ac3_decoder_thread.h"
|
||||
#include "ac3_adec.h"
|
||||
|
||||
#define AC3DEC_FRAME_SIZE (2*1536)
|
||||
|
||||
/*****************************************************************************
|
||||
* Local prototypes
|
||||
*****************************************************************************/
|
||||
static int InitThread (ac3dec_thread_t * p_adec);
|
||||
static void RunThread (ac3dec_thread_t * p_adec);
|
||||
static void ErrorThread (ac3dec_thread_t * p_adec);
|
||||
static void EndThread (ac3dec_thread_t * p_adec);
|
||||
static void BitstreamCallback ( bit_stream_t *p_bit_stream,
|
||||
static int ac3_adec_Probe ( probedata_t * );
|
||||
static int ac3_adec_Run ( decoder_config_t * );
|
||||
static int ac3_adec_Init (ac3dec_thread_t * p_adec);
|
||||
static void ac3_adec_ErrorThread (ac3dec_thread_t * p_adec);
|
||||
static void ac3_adec_EndThread (ac3dec_thread_t * p_adec);
|
||||
static void BitstreamCallback ( bit_stream_t *p_bit_stream,
|
||||
boolean_t b_new_pes );
|
||||
|
||||
/*****************************************************************************
|
||||
* ac3dec_CreateThread: creates an ac3 decoder thread
|
||||
* Capabilities
|
||||
*****************************************************************************/
|
||||
vlc_thread_t ac3dec_CreateThread( adec_config_t * p_config )
|
||||
void _M( adec_getfunctions )( function_list_t * p_function_list )
|
||||
{
|
||||
p_function_list->pf_probe = ac3_adec_Probe;
|
||||
p_function_list->functions.dec.pf_RunThread = ac3_adec_Run;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* Build configuration tree.
|
||||
*****************************************************************************/
|
||||
MODULE_CONFIG_START
|
||||
ADD_WINDOW( "Configuration for ac3 decoder module" )
|
||||
ADD_COMMENT( "Nothing to configure" )
|
||||
MODULE_CONFIG_STOP
|
||||
|
||||
MODULE_INIT_START
|
||||
p_module->i_capabilities = MODULE_CAPABILITY_DEC;
|
||||
p_module->psz_longname = "Ac3 sofware decoder";
|
||||
MODULE_INIT_STOP
|
||||
|
||||
MODULE_ACTIVATE_START
|
||||
_M( adec_getfunctions )( &p_module->p_functions->dec );
|
||||
MODULE_ACTIVATE_STOP
|
||||
|
||||
MODULE_DEACTIVATE_START
|
||||
MODULE_DEACTIVATE_STOP
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* ac3_adec_Probe: probe the decoder and return score
|
||||
*****************************************************************************
|
||||
* Tries to launch a decoder and return score so that the interface is able
|
||||
* to chose.
|
||||
*****************************************************************************/
|
||||
static int ac3_adec_Probe( probedata_t *p_data )
|
||||
{
|
||||
if( p_data->i_type == AC3_AUDIO_ES )
|
||||
return( 50 );
|
||||
else
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* ac3_adec_Run: this function is called just after the thread is created
|
||||
*****************************************************************************/
|
||||
static int ac3_adec_Run ( decoder_config_t * p_config )
|
||||
{
|
||||
ac3dec_thread_t * p_ac3thread;
|
||||
int sync;
|
||||
|
||||
intf_DbgMsg( "ac3dec debug: creating ac3 decoder thread" );
|
||||
intf_DbgMsg( "ac3_adec debug: ac3_adec thread launched, initializing" );
|
||||
|
||||
/* Allocate the memory needed to store the thread's structure */
|
||||
p_ac3thread = (ac3dec_thread_t *)memalign(16, sizeof(ac3dec_thread_t));
|
||||
@ -87,175 +137,18 @@ vlc_thread_t ac3dec_CreateThread( adec_config_t * p_config )
|
||||
if(p_ac3thread == NULL)
|
||||
{
|
||||
intf_ErrMsg ( "ac3dec error: not enough memory "
|
||||
"for ac3dec_CreateThread() to create the new thread");
|
||||
return 0;
|
||||
"for ac3_adec_Run() to allocate p_ac3thread" );
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize the thread properties
|
||||
*/
|
||||
p_ac3thread->p_config = p_config;
|
||||
p_ac3thread->p_fifo = p_config->decoder_config.p_decoder_fifo;
|
||||
p_ac3thread->ac3_decoder = memalign(16, sizeof(ac3dec_t));
|
||||
|
||||
/*
|
||||
* Choose the best downmix module
|
||||
*/
|
||||
#define DOWNMIX p_ac3thread->ac3_decoder->downmix
|
||||
DOWNMIX.p_module = module_Need( MODULE_CAPABILITY_DOWNMIX, NULL );
|
||||
|
||||
if( DOWNMIX.p_module == NULL )
|
||||
if( ac3_adec_Init( p_ac3thread ) )
|
||||
{
|
||||
intf_ErrMsg( "ac3dec error: no suitable downmix module" );
|
||||
free( p_ac3thread->ac3_decoder );
|
||||
free( p_ac3thread );
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
#define F DOWNMIX.p_module->p_functions->downmix.functions.downmix
|
||||
DOWNMIX.pf_downmix_3f_2r_to_2ch = F.pf_downmix_3f_2r_to_2ch;
|
||||
DOWNMIX.pf_downmix_2f_2r_to_2ch = F.pf_downmix_2f_2r_to_2ch;
|
||||
DOWNMIX.pf_downmix_3f_1r_to_2ch = F.pf_downmix_3f_1r_to_2ch;
|
||||
DOWNMIX.pf_downmix_2f_1r_to_2ch = F.pf_downmix_2f_1r_to_2ch;
|
||||
DOWNMIX.pf_downmix_3f_0r_to_2ch = F.pf_downmix_3f_0r_to_2ch;
|
||||
DOWNMIX.pf_stream_sample_2ch_to_s16 = F.pf_stream_sample_2ch_to_s16;
|
||||
DOWNMIX.pf_stream_sample_1ch_to_s16 = F.pf_stream_sample_1ch_to_s16;
|
||||
#undef F
|
||||
#undef DOWNMIX
|
||||
|
||||
/*
|
||||
* Choose the best IMDCT module
|
||||
*/
|
||||
p_ac3thread->ac3_decoder->imdct = memalign(16, sizeof(imdct_t));
|
||||
|
||||
#define IMDCT p_ac3thread->ac3_decoder->imdct
|
||||
IMDCT->p_module = module_Need( MODULE_CAPABILITY_IMDCT, NULL );
|
||||
|
||||
if( IMDCT->p_module == NULL )
|
||||
{
|
||||
intf_ErrMsg( "ac3dec error: no suitable IMDCT module" );
|
||||
module_Unneed( p_ac3thread->ac3_decoder->downmix.p_module );
|
||||
free( p_ac3thread->ac3_decoder->imdct );
|
||||
free( p_ac3thread->ac3_decoder );
|
||||
free( p_ac3thread );
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
#define F IMDCT->p_module->p_functions->imdct.functions.imdct
|
||||
IMDCT->pf_imdct_init = F.pf_imdct_init;
|
||||
IMDCT->pf_imdct_256 = F.pf_imdct_256;
|
||||
IMDCT->pf_imdct_256_nol = F.pf_imdct_256_nol;
|
||||
IMDCT->pf_imdct_512 = F.pf_imdct_512;
|
||||
IMDCT->pf_imdct_512_nol = F.pf_imdct_512_nol;
|
||||
#undef F
|
||||
#undef IMDCT
|
||||
|
||||
/* Initialize the ac3 decoder structures */
|
||||
#if defined( __MINGW32__ )
|
||||
p_ac3thread->ac3_decoder->samples_back = memalign(16, 6 * 256 * sizeof(float) + 15);
|
||||
p_ac3thread->ac3_decoder->samples = (float *) (((unsigned long) p_ac3thread->ac3_decoder->samples_back+15) & ~0xFUL);
|
||||
#else
|
||||
p_ac3thread->ac3_decoder->samples = memalign(16, 6 * 256 * sizeof(float));
|
||||
#endif
|
||||
p_ac3thread->ac3_decoder->imdct->buf = memalign(16, N/4 * sizeof(complex_t));
|
||||
p_ac3thread->ac3_decoder->imdct->delay = memalign(16, 6 * 256 * sizeof(float));
|
||||
p_ac3thread->ac3_decoder->imdct->delay1 = memalign(16, 6 * 256 * sizeof(float));
|
||||
p_ac3thread->ac3_decoder->imdct->xcos1 = memalign(16, N/4 * sizeof(float));
|
||||
p_ac3thread->ac3_decoder->imdct->xsin1 = memalign(16, N/4 * sizeof(float));
|
||||
p_ac3thread->ac3_decoder->imdct->xcos2 = memalign(16, N/8 * sizeof(float));
|
||||
p_ac3thread->ac3_decoder->imdct->xsin2 = memalign(16, N/8 * sizeof(float));
|
||||
p_ac3thread->ac3_decoder->imdct->xcos_sin_sse = memalign(16, 128 * 4 * sizeof(float));
|
||||
p_ac3thread->ac3_decoder->imdct->w_2 = memalign(16, 2 * sizeof(complex_t));
|
||||
p_ac3thread->ac3_decoder->imdct->w_4 = memalign(16, 4 * sizeof(complex_t));
|
||||
p_ac3thread->ac3_decoder->imdct->w_8 = memalign(16, 8 * sizeof(complex_t));
|
||||
p_ac3thread->ac3_decoder->imdct->w_16 = memalign(16, 16 * sizeof(complex_t));
|
||||
p_ac3thread->ac3_decoder->imdct->w_32 = memalign(16, 32 * sizeof(complex_t));
|
||||
p_ac3thread->ac3_decoder->imdct->w_64 = memalign(16, 64 * sizeof(complex_t));
|
||||
p_ac3thread->ac3_decoder->imdct->w_1 = memalign(16, sizeof(complex_t));
|
||||
|
||||
ac3_init (p_ac3thread->ac3_decoder);
|
||||
|
||||
/*
|
||||
* Initialize the output properties
|
||||
*/
|
||||
p_ac3thread->p_aout_fifo = NULL;
|
||||
|
||||
/* Spawn the ac3 decoder thread */
|
||||
if (vlc_thread_create(&p_ac3thread->thread_id, "ac3 decoder",
|
||||
(vlc_thread_func_t)RunThread, (void *)p_ac3thread))
|
||||
{
|
||||
intf_ErrMsg( "ac3dec error: can't spawn ac3 decoder thread" );
|
||||
module_Unneed( p_ac3thread->ac3_decoder->downmix.p_module );
|
||||
module_Unneed( p_ac3thread->ac3_decoder->imdct->p_module );
|
||||
free( p_ac3thread->ac3_decoder->imdct->w_1 );
|
||||
free( p_ac3thread->ac3_decoder->imdct->w_64 );
|
||||
free( p_ac3thread->ac3_decoder->imdct->w_32 );
|
||||
free( p_ac3thread->ac3_decoder->imdct->w_16 );
|
||||
free( p_ac3thread->ac3_decoder->imdct->w_8 );
|
||||
free( p_ac3thread->ac3_decoder->imdct->w_4 );
|
||||
free( p_ac3thread->ac3_decoder->imdct->w_2 );
|
||||
free( p_ac3thread->ac3_decoder->imdct->xcos_sin_sse );
|
||||
free( p_ac3thread->ac3_decoder->imdct->xsin2 );
|
||||
free( p_ac3thread->ac3_decoder->imdct->xcos2 );
|
||||
free( p_ac3thread->ac3_decoder->imdct->xsin1 );
|
||||
free( p_ac3thread->ac3_decoder->imdct->xcos1 );
|
||||
free( p_ac3thread->ac3_decoder->imdct->delay1 );
|
||||
free( p_ac3thread->ac3_decoder->imdct->delay );
|
||||
free( p_ac3thread->ac3_decoder->imdct->buf );
|
||||
#if defined( __MINGW32__ )
|
||||
free( p_ac3thread->ac3_decoder->samples_back );
|
||||
#else
|
||||
free( p_ac3thread->ac3_decoder->samples );
|
||||
#endif
|
||||
free( p_ac3thread->ac3_decoder->imdct );
|
||||
free( p_ac3thread->ac3_decoder );
|
||||
free( p_ac3thread );
|
||||
return 0;
|
||||
}
|
||||
|
||||
intf_DbgMsg ("ac3dec debug: ac3 decoder thread (%p) created", p_ac3thread);
|
||||
return p_ac3thread->thread_id;
|
||||
}
|
||||
|
||||
/* Following functions are local */
|
||||
|
||||
/*****************************************************************************
|
||||
* InitThread : initialize an ac3 decoder thread
|
||||
*****************************************************************************/
|
||||
static int InitThread (ac3dec_thread_t * p_ac3thread)
|
||||
{
|
||||
intf_DbgMsg("ac3dec debug: initializing ac3 decoder thread %p",p_ac3thread);
|
||||
|
||||
p_ac3thread->p_config->decoder_config.pf_init_bit_stream(
|
||||
&p_ac3thread->ac3_decoder->bit_stream,
|
||||
p_ac3thread->p_config->decoder_config.p_decoder_fifo,
|
||||
BitstreamCallback, (void *) p_ac3thread );
|
||||
|
||||
/* Creating the audio output fifo */
|
||||
p_ac3thread->p_aout_fifo = aout_CreateFifo( AOUT_ADEC_STEREO_FIFO, 2, 0, 0,
|
||||
AC3DEC_FRAME_SIZE, NULL );
|
||||
if ( p_ac3thread->p_aout_fifo == NULL )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
intf_DbgMsg("ac3dec debug: ac3 decoder thread %p initialized", p_ac3thread);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* RunThread : ac3 decoder thread
|
||||
*****************************************************************************/
|
||||
static void RunThread (ac3dec_thread_t * p_ac3thread)
|
||||
{
|
||||
int sync;
|
||||
|
||||
intf_DbgMsg ("ac3dec debug: running ac3 decoder thread (%p) (pid == %i)", p_ac3thread, getpid());
|
||||
|
||||
/* Initializing the ac3 decoder thread */
|
||||
if (InitThread (p_ac3thread)) /* XXX?? */
|
||||
{
|
||||
p_ac3thread->p_fifo->b_error = 1;
|
||||
intf_ErrMsg( "ac3_adec error : could not initialize thread" );
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
sync = 0;
|
||||
@ -289,11 +182,13 @@ static void RunThread (ac3dec_thread_t * p_ac3thread)
|
||||
|
||||
if (DECODER_FIFO_START(*p_ac3thread->p_fifo)->i_pts)
|
||||
{
|
||||
p_ac3thread->p_aout_fifo->date[p_ac3thread->p_aout_fifo->l_end_frame] =
|
||||
p_ac3thread->p_aout_fifo->date[
|
||||
p_ac3thread->p_aout_fifo->l_end_frame] =
|
||||
DECODER_FIFO_START(*p_ac3thread->p_fifo)->i_pts;
|
||||
DECODER_FIFO_START(*p_ac3thread->p_fifo)->i_pts = 0;
|
||||
} else {
|
||||
p_ac3thread->p_aout_fifo->date[p_ac3thread->p_aout_fifo->l_end_frame] =
|
||||
p_ac3thread->p_aout_fifo->date[
|
||||
p_ac3thread->p_aout_fifo->l_end_frame] =
|
||||
LAST_MDATE;
|
||||
}
|
||||
|
||||
@ -327,17 +222,140 @@ static void RunThread (ac3dec_thread_t * p_ac3thread)
|
||||
/* If b_error is set, the ac3 decoder thread enters the error loop */
|
||||
if (p_ac3thread->p_fifo->b_error)
|
||||
{
|
||||
ErrorThread (p_ac3thread);
|
||||
ac3_adec_ErrorThread (p_ac3thread);
|
||||
}
|
||||
|
||||
/* End of the ac3 decoder thread */
|
||||
EndThread (p_ac3thread);
|
||||
ac3_adec_EndThread (p_ac3thread);
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* ErrorThread : ac3 decoder's RunThread() error loop
|
||||
* ac3_adec_Init: initialize data before entering main loop
|
||||
*****************************************************************************/
|
||||
static void ErrorThread (ac3dec_thread_t * p_ac3thread)
|
||||
static int ac3_adec_Init( ac3dec_thread_t * p_ac3thread )
|
||||
{
|
||||
/*
|
||||
* Thread properties
|
||||
*/
|
||||
p_ac3thread->p_fifo = p_ac3thread->p_config->p_decoder_fifo;
|
||||
p_ac3thread->ac3_decoder = memalign(16, sizeof(ac3dec_t));
|
||||
|
||||
/*
|
||||
* Choose the best downmix module
|
||||
*/
|
||||
#define DOWNMIX p_ac3thread->ac3_decoder->downmix
|
||||
DOWNMIX.p_module = module_Need( MODULE_CAPABILITY_DOWNMIX, NULL );
|
||||
|
||||
if( DOWNMIX.p_module == NULL )
|
||||
{
|
||||
intf_ErrMsg( "ac3dec error: no suitable downmix module" );
|
||||
free( p_ac3thread->ac3_decoder );
|
||||
free( p_ac3thread );
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
#define F DOWNMIX.p_module->p_functions->downmix.functions.downmix
|
||||
DOWNMIX.pf_downmix_3f_2r_to_2ch = F.pf_downmix_3f_2r_to_2ch;
|
||||
DOWNMIX.pf_downmix_2f_2r_to_2ch = F.pf_downmix_2f_2r_to_2ch;
|
||||
DOWNMIX.pf_downmix_3f_1r_to_2ch = F.pf_downmix_3f_1r_to_2ch;
|
||||
DOWNMIX.pf_downmix_2f_1r_to_2ch = F.pf_downmix_2f_1r_to_2ch;
|
||||
DOWNMIX.pf_downmix_3f_0r_to_2ch = F.pf_downmix_3f_0r_to_2ch;
|
||||
DOWNMIX.pf_stream_sample_2ch_to_s16 = F.pf_stream_sample_2ch_to_s16;
|
||||
DOWNMIX.pf_stream_sample_1ch_to_s16 = F.pf_stream_sample_1ch_to_s16;
|
||||
#undef F
|
||||
#undef DOWNMIX
|
||||
|
||||
/*
|
||||
* Choose the best IMDCT module
|
||||
*/
|
||||
p_ac3thread->ac3_decoder->imdct = memalign(16, sizeof(imdct_t));
|
||||
|
||||
#define IMDCT p_ac3thread->ac3_decoder->imdct
|
||||
IMDCT->p_module = module_Need( MODULE_CAPABILITY_IMDCT, NULL );
|
||||
|
||||
if( IMDCT->p_module == NULL )
|
||||
{
|
||||
intf_ErrMsg( "ac3dec error: no suitable IMDCT module" );
|
||||
module_Unneed( p_ac3thread->ac3_decoder->downmix.p_module );
|
||||
free( p_ac3thread->ac3_decoder->imdct );
|
||||
free( p_ac3thread->ac3_decoder );
|
||||
free( p_ac3thread );
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
#define F IMDCT->p_module->p_functions->imdct.functions.imdct
|
||||
IMDCT->pf_imdct_init = F.pf_imdct_init;
|
||||
IMDCT->pf_imdct_256 = F.pf_imdct_256;
|
||||
IMDCT->pf_imdct_256_nol = F.pf_imdct_256_nol;
|
||||
IMDCT->pf_imdct_512 = F.pf_imdct_512;
|
||||
IMDCT->pf_imdct_512_nol = F.pf_imdct_512_nol;
|
||||
#undef F
|
||||
#undef IMDCT
|
||||
|
||||
/* Initialize the ac3 decoder structures */
|
||||
#if defined( __MINGW32__ )
|
||||
p_ac3thread->ac3_decoder->samples_back = memalign(16, 6 * 256 *
|
||||
sizeof(float) + 15);
|
||||
p_ac3thread->ac3_decoder->samples = (float *) (((unsigned long)
|
||||
p_ac3thread->ac3_decoder->samples_back+15) & ~0xFUL);
|
||||
#else
|
||||
p_ac3thread->ac3_decoder->samples = memalign(16, 6 * 256 * sizeof(float));
|
||||
#endif
|
||||
p_ac3thread->ac3_decoder->imdct->buf = memalign(16, N/4 * sizeof(complex_t));
|
||||
p_ac3thread->ac3_decoder->imdct->delay = memalign(16, 6 * 256 * sizeof(float));
|
||||
p_ac3thread->ac3_decoder->imdct->delay1 = memalign(16, 6 * 256 * sizeof(float));
|
||||
p_ac3thread->ac3_decoder->imdct->xcos1 = memalign(16, N/4 * sizeof(float));
|
||||
p_ac3thread->ac3_decoder->imdct->xsin1 = memalign(16, N/4 * sizeof(float));
|
||||
p_ac3thread->ac3_decoder->imdct->xcos2 = memalign(16, N/8 * sizeof(float));
|
||||
p_ac3thread->ac3_decoder->imdct->xsin2 = memalign(16, N/8 * sizeof(float));
|
||||
p_ac3thread->ac3_decoder->imdct->xcos_sin_sse = memalign(16, 128 * 4 * sizeof(float));
|
||||
p_ac3thread->ac3_decoder->imdct->w_2 = memalign(16, 2 * sizeof(complex_t));
|
||||
p_ac3thread->ac3_decoder->imdct->w_4 = memalign(16, 4 * sizeof(complex_t));
|
||||
p_ac3thread->ac3_decoder->imdct->w_8 = memalign(16, 8 * sizeof(complex_t));
|
||||
p_ac3thread->ac3_decoder->imdct->w_16 = memalign(16, 16 * sizeof(complex_t));
|
||||
p_ac3thread->ac3_decoder->imdct->w_32 = memalign(16, 32 * sizeof(complex_t));
|
||||
p_ac3thread->ac3_decoder->imdct->w_64 = memalign(16, 64 * sizeof(complex_t));
|
||||
p_ac3thread->ac3_decoder->imdct->w_1 = memalign(16, sizeof(complex_t));
|
||||
|
||||
ac3_init (p_ac3thread->ac3_decoder);
|
||||
|
||||
/*
|
||||
* Initialize the output properties
|
||||
*/
|
||||
p_ac3thread->p_aout_fifo = NULL;
|
||||
|
||||
intf_DbgMsg ( "ac3_adec debug: ac3_adec thread (%p) initialized",
|
||||
p_ac3thread );
|
||||
|
||||
/*
|
||||
* Bit stream
|
||||
*/
|
||||
p_ac3thread->p_config->pf_init_bit_stream(
|
||||
&p_ac3thread->ac3_decoder->bit_stream,
|
||||
p_ac3thread->p_config->p_decoder_fifo,
|
||||
BitstreamCallback, (void *) p_ac3thread );
|
||||
|
||||
/* Creating the audio output fifo */
|
||||
p_ac3thread->p_aout_fifo = aout_CreateFifo( AOUT_ADEC_STEREO_FIFO, 2, 0, 0,
|
||||
AC3DEC_FRAME_SIZE, NULL );
|
||||
if ( p_ac3thread->p_aout_fifo == NULL )
|
||||
{
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
intf_DbgMsg("ac3dec debug: ac3 decoder thread %p initialized", p_ac3thread);
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* ac3_adec_ErrorThread : ac3 decoder's RunThread() error loop
|
||||
*****************************************************************************/
|
||||
static void ac3_adec_ErrorThread (ac3dec_thread_t * p_ac3thread)
|
||||
{
|
||||
/* We take the lock, because we are going to read/write the start/end
|
||||
* indexes of the decoder fifo */
|
||||
@ -349,7 +367,8 @@ static void ErrorThread (ac3dec_thread_t * p_ac3thread)
|
||||
/* Trash all received PES packets */
|
||||
while (!DECODER_FIFO_ISEMPTY(*p_ac3thread->p_fifo))
|
||||
{
|
||||
p_ac3thread->p_fifo->pf_delete_pes(p_ac3thread->p_fifo->p_packets_mgt,
|
||||
p_ac3thread->p_fifo->pf_delete_pes(
|
||||
p_ac3thread->p_fifo->p_packets_mgt,
|
||||
DECODER_FIFO_START(*p_ac3thread->p_fifo));
|
||||
DECODER_FIFO_INCSTART (*p_ac3thread->p_fifo);
|
||||
}
|
||||
@ -364,9 +383,9 @@ static void ErrorThread (ac3dec_thread_t * p_ac3thread)
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* EndThread : ac3 decoder thread destruction
|
||||
* ac3_adec_EndThread : ac3 decoder thread destruction
|
||||
*****************************************************************************/
|
||||
static void EndThread (ac3dec_thread_t * p_ac3thread)
|
||||
static void ac3_adec_EndThread (ac3dec_thread_t * p_ac3thread)
|
||||
{
|
||||
intf_DbgMsg ("ac3dec debug: destroying ac3 decoder thread %p", p_ac3thread);
|
||||
|
@ -1,8 +1,8 @@
|
||||
/*****************************************************************************
|
||||
* ac3_decoder_thread.h : ac3 decoder thread interface
|
||||
* ac3_adec.h : ac3 decoder thread interface
|
||||
*****************************************************************************
|
||||
* Copyright (C) 1999, 2000 VideoLAN
|
||||
* $Id: ac3_decoder_thread.h,v 1.10 2001/10/30 19:34:53 reno Exp $
|
||||
* $Id: ac3_adec.h,v 1.1 2001/11/13 12:09:17 henri Exp $
|
||||
*
|
||||
* Authors: Michel Kaempf <maxx@via.ecp.fr>
|
||||
*
|
||||
@ -42,7 +42,7 @@ typedef struct ac3dec_thread_s
|
||||
*/
|
||||
decoder_fifo_t * p_fifo; /* stores the PES stream data */
|
||||
int sync_ptr; /* sync ptr from ac3 magic header */
|
||||
adec_config_t * p_config;
|
||||
decoder_config_t * p_config;
|
||||
|
||||
/*
|
||||
* Output properties
|
||||
@ -54,4 +54,4 @@ typedef struct ac3dec_thread_s
|
||||
/*****************************************************************************
|
||||
* Prototypes
|
||||
*****************************************************************************/
|
||||
vlc_thread_t ac3dec_CreateThread( adec_config_t * p_config );
|
||||
vlc_thread_t ac3dec_CreateThread( decoder_config_t * p_config );
|
@ -2,7 +2,7 @@
|
||||
* ac3_bit_allocate.c: ac3 allocation tables
|
||||
*****************************************************************************
|
||||
* Copyright (C) 2000 VideoLAN
|
||||
* $Id: ac3_bit_allocate.c,v 1.22 2001/05/15 16:19:42 sam Exp $
|
||||
* $Id: ac3_bit_allocate.c,v 1.1 2001/11/13 12:09:17 henri Exp $
|
||||
*
|
||||
* Authors: Michel Kaempf <maxx@via.ecp.fr>
|
||||
* Aaron Holtzman <aholtzma@engr.uvic.ca>
|
@ -2,7 +2,7 @@
|
||||
* ac3_decoder.c: core ac3 decoder
|
||||
*****************************************************************************
|
||||
* Copyright (C) 1999, 2000 VideoLAN
|
||||
* $Id: ac3_decoder.c,v 1.35 2001/10/30 19:34:53 reno Exp $
|
||||
* $Id: ac3_decoder.c,v 1.1 2001/11/13 12:09:17 henri Exp $
|
||||
*
|
||||
* Authors: Michel Kaempf <maxx@via.ecp.fr>
|
||||
* Michel Lespinasse <walken@zoy.org>
|
||||
@ -34,18 +34,20 @@
|
||||
#include "common.h"
|
||||
#include "threads.h"
|
||||
#include "mtime.h"
|
||||
|
||||
#include "intf_msg.h" /* intf_DbgMsg(), intf_ErrMsg() */
|
||||
|
||||
#include "audio_output.h"
|
||||
|
||||
#include "modules_export.h"
|
||||
|
||||
#include "stream_control.h"
|
||||
#include "input_ext-dec.h"
|
||||
|
||||
#include "audio_output.h"
|
||||
|
||||
#include "ac3_imdct.h"
|
||||
#include "ac3_downmix.h"
|
||||
#include "ac3_decoder.h"
|
||||
#include "ac3_decoder_thread.h" /* ac3dec_thread_t */
|
||||
#include "ac3_adec.h" /* ac3dec_thread_t */
|
||||
|
||||
#include "ac3_internal.h"
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ac3_decoder.h : ac3 decoder interface
|
||||
*****************************************************************************
|
||||
* Copyright (C) 1999, 2000 VideoLAN
|
||||
* $Id: ac3_decoder.h,v 1.13 2001/10/31 11:55:53 reno Exp $
|
||||
* $Id: ac3_decoder.h,v 1.1 2001/11/13 12:09:17 henri Exp $
|
||||
*
|
||||
* Authors: Michel Kaempf <maxx@via.ecp.fr>
|
||||
* Renaud Dartus <reno@videolan.org>
|
@ -2,7 +2,7 @@
|
||||
* ac3_exponent.c: ac3 exponent calculations
|
||||
*****************************************************************************
|
||||
* Copyright (C) 1999, 2000 VideoLAN
|
||||
* $Id: ac3_exponent.c,v 1.25 2001/05/15 16:19:42 sam Exp $
|
||||
* $Id: ac3_exponent.c,v 1.1 2001/11/13 12:09:17 henri Exp $
|
||||
*
|
||||
* Authors: Michel Kaempf <maxx@via.ecp.fr>
|
||||
* Michel Lespinasse <walken@zoy.org>
|
||||
@ -34,13 +34,15 @@
|
||||
#include "common.h"
|
||||
#include "threads.h"
|
||||
#include "mtime.h"
|
||||
|
||||
#include "intf_msg.h" /* intf_DbgMsg(), intf_ErrMsg() */
|
||||
|
||||
#include "audio_output.h"
|
||||
|
||||
#include "modules_export.h"
|
||||
|
||||
#include "stream_control.h"
|
||||
#include "input_ext-dec.h"
|
||||
|
||||
#include "audio_output.h"
|
||||
|
||||
#include "ac3_imdct.h"
|
||||
#include "ac3_downmix.h"
|
@ -2,7 +2,7 @@
|
||||
* ac3_exponent.h: ac3 exponent calculations
|
||||
*****************************************************************************
|
||||
* Copyright (C) 1999, 2000 VideoLAN
|
||||
* $Id: ac3_exponent.h,v 1.5 2001/05/15 16:19:42 sam Exp $
|
||||
* $Id: ac3_exponent.h,v 1.1 2001/11/13 12:09:17 henri Exp $
|
||||
*
|
||||
* Authors: Michel Kaempf <maxx@via.ecp.fr>
|
||||
* Michel Lespinasse <walken@zoy.org>
|
@ -2,7 +2,7 @@
|
||||
* ac3_imdct.c: ac3 DCT
|
||||
*****************************************************************************
|
||||
* Copyright (C) 1999, 2000 VideoLAN
|
||||
* $Id: ac3_imdct.c,v 1.22 2001/10/30 19:34:53 reno Exp $
|
||||
* $Id: ac3_imdct.c,v 1.1 2001/11/13 12:09:17 henri Exp $
|
||||
*
|
||||
* Authors: Michel Kaempf <maxx@via.ecp.fr>
|
||||
* Aaron Holtzman <aholtzma@engr.uvic.ca>
|
@ -2,7 +2,7 @@
|
||||
* ac3_internals.h: needed by the ac3 decoder
|
||||
*****************************************************************************
|
||||
* Copyright (C) 2000 VideoLAN
|
||||
* $Id: ac3_internal.h,v 1.10 2001/05/15 16:19:42 sam Exp $
|
||||
* $Id: ac3_internal.h,v 1.1 2001/11/13 12:09:17 henri Exp $
|
||||
*
|
||||
* Authors: Michel Lespinasse <walken@zoy.org>
|
||||
*
|
@ -2,7 +2,7 @@
|
||||
* ac3_mantissa.c: ac3 mantissa computation
|
||||
*****************************************************************************
|
||||
* Copyright (C) 1999, 2000, 2001 VideoLAN
|
||||
* $Id: ac3_mantissa.c,v 1.30 2001/10/30 19:34:53 reno Exp $
|
||||
* $Id: ac3_mantissa.c,v 1.1 2001/11/13 12:09:17 henri Exp $
|
||||
*
|
||||
* Authors: Michel Kaempf <maxx@via.ecp.fr>
|
||||
* Aaron Holtzman <aholtzma@engr.uvic.ca>
|
||||
@ -34,13 +34,15 @@
|
||||
#include "common.h"
|
||||
#include "threads.h"
|
||||
#include "mtime.h"
|
||||
|
||||
#include "intf_msg.h"
|
||||
|
||||
#include "audio_output.h"
|
||||
|
||||
#include "modules_export.h"
|
||||
|
||||
#include "stream_control.h"
|
||||
#include "input_ext-dec.h"
|
||||
|
||||
#include "audio_output.h"
|
||||
|
||||
#include "ac3_imdct.h"
|
||||
#include "ac3_downmix.h"
|
@ -2,7 +2,7 @@
|
||||
* ac3_mantissa.h: ac3 mantissa computation
|
||||
*****************************************************************************
|
||||
* Copyright (C) 1999, 2000, 2001 VideoLAN
|
||||
* $Id: ac3_mantissa.h,v 1.5 2001/10/30 19:34:53 reno Exp $
|
||||
* $Id: ac3_mantissa.h,v 1.1 2001/11/13 12:09:17 henri Exp $
|
||||
*
|
||||
* Authors: Michel Kaempf <maxx@via.ecp.fr>
|
||||
* Aaron Holtzman <aholtzma@engr.uvic.ca>
|
@ -2,7 +2,7 @@
|
||||
* ac3_parse.c: ac3 parsing procedures
|
||||
*****************************************************************************
|
||||
* Copyright (C) 1999, 2000, 2001 VideoLAN
|
||||
* $Id: ac3_parse.c,v 1.24 2001/08/22 17:21:45 massiot Exp $
|
||||
* $Id: ac3_parse.c,v 1.1 2001/11/13 12:09:17 henri Exp $
|
||||
*
|
||||
* Authors: Michel Kaempf <maxx@via.ecp.fr>
|
||||
* Aaron Holtzman <aholtzma@engr.uvic.ca>
|
||||
@ -35,18 +35,20 @@
|
||||
|
||||
#include "threads.h"
|
||||
#include "mtime.h"
|
||||
|
||||
#include "intf_msg.h"
|
||||
|
||||
#include "audio_output.h"
|
||||
|
||||
#include "modules_export.h"
|
||||
|
||||
#include "stream_control.h"
|
||||
#include "input_ext-dec.h"
|
||||
|
||||
#include "audio_output.h"
|
||||
|
||||
#include "ac3_imdct.h"
|
||||
#include "ac3_downmix.h"
|
||||
#include "ac3_decoder.h"
|
||||
#include "ac3_decoder_thread.h" /* ac3dec_thread_t */
|
||||
#include "ac3_adec.h" /* ac3dec_thread_t */
|
||||
|
||||
#include "ac3_internal.h" /* EXP_REUSE */
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ac3_rematrix.c: ac3 audio rematrixing
|
||||
*****************************************************************************
|
||||
* Copyright (C) 1999, 2000 VideoLAN
|
||||
* $Id: ac3_rematrix.c,v 1.19 2001/10/30 19:34:53 reno Exp $
|
||||
* $Id: ac3_rematrix.c,v 1.1 2001/11/13 12:09:17 henri Exp $
|
||||
*
|
||||
* Authors: Michel Kaempf <maxx@via.ecp.fr>
|
||||
* Aaron Holtzman <aholtzma@engr.uvic.ca>
|
29
plugins/ac3_spdif/Makefile
Normal file
29
plugins/ac3_spdif/Makefile
Normal file
@ -0,0 +1,29 @@
|
||||
###############################################################################
|
||||
# vlc (VideoLAN Client) AC3 spdif audio decoder module makefile
|
||||
# (c)2001 VideoLAN
|
||||
###############################################################################
|
||||
|
||||
#
|
||||
# Objects
|
||||
#
|
||||
PLUGIN_C = ac3_spdif.o ac3_iec958.o
|
||||
BUILTIN_C = $(PLUGIN_C:%.o=BUILTIN_%.o)
|
||||
|
||||
ALL_OBJ = $(PLUGIN_C) $(BUILTIN_C)
|
||||
#
|
||||
# Virtual targets
|
||||
#
|
||||
|
||||
include ../../Makefile.modules
|
||||
|
||||
#
|
||||
# Real targets
|
||||
#
|
||||
|
||||
../ac3_spdif.so: $(PLUGIN_C)
|
||||
$(CC) $(PCFLAGS) -o $@ $^ $(PLCFLAGS)
|
||||
|
||||
../ac3_spdif.a: $(BUILTIN_C)
|
||||
ar r $@ $^
|
||||
$(RANLIB) $@
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ac3_iec958.c: ac3 to spdif converter
|
||||
*****************************************************************************
|
||||
* Copyright (C) 2001 VideoLAN
|
||||
* $Id: ac3_iec958.c,v 1.6 2001/09/29 14:52:01 bozo Exp $
|
||||
* $Id: ac3_iec958.c,v 1.1 2001/11/13 12:09:17 henri Exp $
|
||||
*
|
||||
* Authors: Stéphane Borel <stef@via.ecp.fr>
|
||||
* Juha Yrjola <jyrjola@cc.hut.fi>
|
||||
@ -41,13 +41,15 @@
|
||||
#include "common.h"
|
||||
#include "threads.h"
|
||||
#include "mtime.h"
|
||||
|
||||
#include "intf_msg.h" /* intf_DbgMsg(), intf_ErrMsg() */
|
||||
|
||||
#include "audio_output.h"
|
||||
|
||||
#include "modules_export.h"
|
||||
|
||||
#include "stream_control.h"
|
||||
#include "input_ext-dec.h"
|
||||
|
||||
#include "audio_output.h"
|
||||
|
||||
#include "ac3_spdif.h"
|
||||
#include "ac3_iec958.h"
|
@ -2,7 +2,7 @@
|
||||
* ac3_iec958.h: ac3 to spdif converter headers
|
||||
*****************************************************************************
|
||||
* Copyright (C) 2001 VideoLAN
|
||||
* $Id: ac3_iec958.h,v 1.2 2001/05/01 04:18:18 sam Exp $
|
||||
* $Id: ac3_iec958.h,v 1.1 2001/11/13 12:09:17 henri Exp $
|
||||
*
|
||||
* Authors: Stéphane Borel <stef@via.ecp.fr>
|
||||
* Juha Yrjola <jyrjola@cc.hut.fi>
|
@ -2,7 +2,7 @@
|
||||
* ac3_spdif.c: ac3 pass-through to external decoder with enabled soundcard
|
||||
*****************************************************************************
|
||||
* Copyright (C) 2001 VideoLAN
|
||||
* $Id: ac3_spdif.c,v 1.12 2001/09/30 20:25:13 bozo Exp $
|
||||
* $Id: ac3_spdif.c,v 1.1 2001/11/13 12:09:17 henri Exp $
|
||||
*
|
||||
* Authors: Stéphane Borel <stef@via.ecp.fr>
|
||||
* Juha Yrjola <jyrjola@cc.hut.fi>
|
||||
@ -23,6 +23,9 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
|
||||
*****************************************************************************/
|
||||
|
||||
#define MODULE_NAME ac3_spdif
|
||||
#include "modules_inner.h"
|
||||
|
||||
/*****************************************************************************
|
||||
* Preamble
|
||||
*****************************************************************************/
|
||||
@ -41,14 +44,16 @@
|
||||
#include "common.h"
|
||||
#include "threads.h"
|
||||
#include "mtime.h"
|
||||
|
||||
#include "intf_msg.h" /* intf_DbgMsg(), intf_ErrMsg() */
|
||||
|
||||
#include "audio_output.h"
|
||||
|
||||
#include "modules.h"
|
||||
#include "modules_export.h"
|
||||
|
||||
#include "stream_control.h"
|
||||
#include "input_ext-dec.h"
|
||||
|
||||
#include "audio_output.h"
|
||||
|
||||
#include "ac3_spdif.h"
|
||||
#include "ac3_iec958.h"
|
||||
|
||||
@ -57,20 +62,72 @@
|
||||
/****************************************************************************
|
||||
* Local Prototypes
|
||||
****************************************************************************/
|
||||
static int InitThread ( ac3_spdif_thread_t * );
|
||||
static void RunThread ( ac3_spdif_thread_t * );
|
||||
static void ErrorThread ( ac3_spdif_thread_t * );
|
||||
static void EndThread ( ac3_spdif_thread_t * );
|
||||
static int ac3_spdif_Probe ( probedata_t * );
|
||||
static int ac3_spdif_Run ( decoder_config_t * );
|
||||
static int ac3_spdif_Init ( ac3_spdif_thread_t * );
|
||||
static void ac3_spdif_ErrorThread ( ac3_spdif_thread_t * );
|
||||
static void ac3_spdif_EndThread ( ac3_spdif_thread_t * );
|
||||
static void BitstreamCallback( bit_stream_t *, boolean_t );
|
||||
|
||||
/*****************************************************************************
|
||||
* Capabilities
|
||||
*****************************************************************************/
|
||||
void _M( adec_getfunctions )( function_list_t * p_function_list )
|
||||
{
|
||||
p_function_list->pf_probe = ac3_spdif_Probe;
|
||||
p_function_list->functions.dec.pf_RunThread = ac3_spdif_Run;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* Build configuration tree.
|
||||
*****************************************************************************/
|
||||
MODULE_CONFIG_START
|
||||
ADD_WINDOW( "Configuration for ac3 spdif decoder module" )
|
||||
ADD_COMMENT( "Nothing to configure" )
|
||||
MODULE_CONFIG_STOP
|
||||
|
||||
MODULE_INIT_START
|
||||
p_module->i_capabilities = MODULE_CAPABILITY_DEC;
|
||||
p_module->psz_longname = "Ac3 SPDIF decoder for AC3 pass-through";
|
||||
MODULE_INIT_STOP
|
||||
|
||||
MODULE_ACTIVATE_START
|
||||
_M( adec_getfunctions )( &p_module->p_functions->dec );
|
||||
MODULE_ACTIVATE_STOP
|
||||
|
||||
MODULE_DEACTIVATE_START
|
||||
MODULE_DEACTIVATE_STOP
|
||||
|
||||
/*****************************************************************************
|
||||
* ac3_spdif_Probe: probe the decoder and return score
|
||||
*****************************************************************************
|
||||
* Tries to launch a decoder and return score so that the interface is able
|
||||
* to chose.
|
||||
*****************************************************************************/
|
||||
static int ac3_spdif_Probe( probedata_t *p_data )
|
||||
{
|
||||
if( main_GetIntVariable( AOUT_SPDIF_VAR, 0 ) &&
|
||||
p_data->i_type == AC3_AUDIO_ES )
|
||||
return( 100 );
|
||||
else
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* spdif_CreateThread: initialize the spdif thread
|
||||
* ac3_spdif_Run: the whole thing
|
||||
****************************************************************************
|
||||
* This function is called just after the thread is launched.
|
||||
****************************************************************************/
|
||||
vlc_thread_t spdif_CreateThread( adec_config_t * p_config )
|
||||
static int ac3_spdif_Run( decoder_config_t * p_config )
|
||||
{
|
||||
ac3_spdif_thread_t * p_spdif;
|
||||
mtime_t i_frame_time;
|
||||
boolean_t b_sync;
|
||||
/* PTS of the current frame */
|
||||
mtime_t i_current_pts = 0;
|
||||
|
||||
intf_DbgMsg( "spdif debug: creating ac3 pass-through thread" );
|
||||
intf_DbgMsg( "spdif debug: ac3_spdif thread created, initializing." );
|
||||
|
||||
/* Allocate the memory needed to store the thread's structure */
|
||||
p_spdif = malloc( sizeof(ac3_spdif_thread_t) );
|
||||
@ -79,130 +136,22 @@ vlc_thread_t spdif_CreateThread( adec_config_t * p_config )
|
||||
{
|
||||
intf_ErrMsg ( "spdif error: not enough memory "
|
||||
"for spdif_CreateThread() to create the new thread");
|
||||
return 0;
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
p_spdif->p_config = p_config;
|
||||
|
||||
/* Temporary buffer to store ac3 frames to be transformed */
|
||||
p_spdif->p_ac3 = malloc( SPDIF_FRAME_SIZE );
|
||||
|
||||
if( p_spdif->p_ac3 == NULL )
|
||||
if (ac3_spdif_Init( p_spdif ) )
|
||||
{
|
||||
free( p_spdif->p_ac3 );
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize the thread properties
|
||||
*/
|
||||
p_spdif->p_config = p_config;
|
||||
p_spdif->p_fifo = p_config->decoder_config.p_decoder_fifo;
|
||||
|
||||
p_spdif->p_aout_fifo = NULL;
|
||||
|
||||
/* Spawn the ac3 to spdif thread */
|
||||
if (vlc_thread_create(&p_spdif->thread_id, "spdif",
|
||||
(vlc_thread_func_t)RunThread, (void *)p_spdif))
|
||||
{
|
||||
intf_ErrMsg( "spdif error: can't spawn spdif thread" );
|
||||
free( p_spdif->p_ac3 );
|
||||
free( p_spdif );
|
||||
return 0;
|
||||
}
|
||||
|
||||
intf_DbgMsg( "spdif debug: spdif thread (%p) created", p_spdif );
|
||||
|
||||
return p_spdif->thread_id;
|
||||
}
|
||||
|
||||
/*
|
||||
* Local functions
|
||||
*/
|
||||
|
||||
/****************************************************************************
|
||||
* InitThread: initialize thread data and create output fifo
|
||||
****************************************************************************/
|
||||
static int InitThread( ac3_spdif_thread_t * p_spdif )
|
||||
{
|
||||
boolean_t b_sync = 0;
|
||||
|
||||
p_spdif->p_config->decoder_config.pf_init_bit_stream(
|
||||
&p_spdif->bit_stream,
|
||||
p_spdif->p_config->decoder_config.p_decoder_fifo,
|
||||
BitstreamCallback, (void*)p_spdif );
|
||||
|
||||
/* Creating the audio output fifo */
|
||||
p_spdif->p_aout_fifo = aout_CreateFifo( AOUT_ADEC_SPDIF_FIFO, 1, 48000, 0,
|
||||
SPDIF_FRAME_SIZE, NULL );
|
||||
|
||||
if( p_spdif->p_aout_fifo == NULL )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
intf_WarnMsg( 3, "spdif: aout fifo #%d created",
|
||||
p_spdif->p_aout_fifo->i_fifo );
|
||||
|
||||
/* Sync word */
|
||||
p_spdif->p_ac3[0] = 0x0b;
|
||||
p_spdif->p_ac3[1] = 0x77;
|
||||
|
||||
/* Find syncword */
|
||||
while( !b_sync )
|
||||
{
|
||||
while( GetBits( &p_spdif->bit_stream, 8 ) != 0x0b );
|
||||
p_spdif->i_real_pts = p_spdif->i_pts;
|
||||
p_spdif->i_pts = 0;
|
||||
b_sync = ( ShowBits( &p_spdif->bit_stream, 8 ) == 0x77 );
|
||||
}
|
||||
RemoveBits( &p_spdif->bit_stream, 8 );
|
||||
|
||||
/* Check stream properties */
|
||||
if( ac3_iec958_parse_syncinfo( p_spdif ) < 0 )
|
||||
{
|
||||
intf_ErrMsg( "spdif error: stream not valid");
|
||||
|
||||
aout_DestroyFifo( p_spdif->p_aout_fifo );
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Check that we can handle the rate
|
||||
* FIXME: we should check that we have the same rate for all fifos
|
||||
* but all rates should be supported by the decoder (32, 44.1, 48) */
|
||||
if( p_spdif->ac3_info.i_sample_rate != 48000 )
|
||||
{
|
||||
intf_ErrMsg( "spdif error: Only 48000 Hz streams supported");
|
||||
|
||||
aout_DestroyFifo( p_spdif->p_aout_fifo );
|
||||
return -1;
|
||||
}
|
||||
p_spdif->p_aout_fifo->l_rate = p_spdif->ac3_info.i_sample_rate;
|
||||
|
||||
GetChunk( &p_spdif->bit_stream, p_spdif->p_ac3 + sizeof(sync_frame_t),
|
||||
p_spdif->ac3_info.i_frame_size - sizeof(sync_frame_t) );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* RunThread: loop that reads ac3 ES and transform it to
|
||||
* an spdif compliant stream.
|
||||
****************************************************************************/
|
||||
static void RunThread( ac3_spdif_thread_t * p_spdif )
|
||||
{
|
||||
mtime_t i_frame_time;
|
||||
boolean_t b_sync;
|
||||
/* PTS of the current frame */
|
||||
mtime_t i_current_pts = 0;
|
||||
|
||||
/* Initializing the spdif decoder thread */
|
||||
if( InitThread( p_spdif ) )
|
||||
{
|
||||
p_spdif->p_fifo->b_error = 1;
|
||||
intf_ErrMsg( "spdif error: could not initialize thread" );
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
/* Compute the theorical duration of an ac3 frame */
|
||||
i_frame_time = 1000000 * AC3_FRAME_SIZE /
|
||||
p_spdif->ac3_info.i_sample_rate;
|
||||
|
||||
intf_DbgMsg( "spdif debug: ac3_spdif thread (%p) initialized", p_spdif );
|
||||
|
||||
while( !p_spdif->p_fifo->b_die && !p_spdif->p_fifo->b_error )
|
||||
{
|
||||
@ -264,19 +213,99 @@ static void RunThread( ac3_spdif_thread_t * p_spdif )
|
||||
/* If b_error is set, the ac3 spdif thread enters the error loop */
|
||||
if( p_spdif->p_fifo->b_error )
|
||||
{
|
||||
ErrorThread( p_spdif );
|
||||
ac3_spdif_ErrorThread( p_spdif );
|
||||
}
|
||||
|
||||
/* End of the ac3 decoder thread */
|
||||
EndThread( p_spdif );
|
||||
|
||||
return;
|
||||
ac3_spdif_EndThread( p_spdif );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* ac3_spdif_Init: initialize thread data and create output fifo
|
||||
****************************************************************************/
|
||||
static int ac3_spdif_Init( ac3_spdif_thread_t * p_spdif )
|
||||
{
|
||||
boolean_t b_sync = 0;
|
||||
|
||||
/* Temporary buffer to store ac3 frames to be transformed */
|
||||
p_spdif->p_ac3 = malloc( SPDIF_FRAME_SIZE );
|
||||
|
||||
if( p_spdif->p_ac3 == NULL )
|
||||
{
|
||||
free( p_spdif->p_ac3 );
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize the thread properties
|
||||
*/
|
||||
p_spdif->p_fifo = p_spdif->p_config->p_decoder_fifo;
|
||||
|
||||
p_spdif->p_config->pf_init_bit_stream(
|
||||
&p_spdif->bit_stream,
|
||||
p_spdif->p_config->p_decoder_fifo,
|
||||
BitstreamCallback, (void*)p_spdif );
|
||||
|
||||
/* Creating the audio output fifo */
|
||||
p_spdif->p_aout_fifo = aout_CreateFifo( AOUT_ADEC_SPDIF_FIFO, 1, 48000, 0,
|
||||
SPDIF_FRAME_SIZE, NULL );
|
||||
|
||||
if( p_spdif->p_aout_fifo == NULL )
|
||||
{
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
intf_WarnMsg( 3, "spdif: aout fifo #%d created",
|
||||
p_spdif->p_aout_fifo->i_fifo );
|
||||
|
||||
/* Sync word */
|
||||
p_spdif->p_ac3[0] = 0x0b;
|
||||
p_spdif->p_ac3[1] = 0x77;
|
||||
|
||||
/* Find syncword */
|
||||
while( !b_sync )
|
||||
{
|
||||
while( GetBits( &p_spdif->bit_stream, 8 ) != 0x0b );
|
||||
p_spdif->i_real_pts = p_spdif->i_pts;
|
||||
p_spdif->i_pts = 0;
|
||||
b_sync = ( ShowBits( &p_spdif->bit_stream, 8 ) == 0x77 );
|
||||
}
|
||||
RemoveBits( &p_spdif->bit_stream, 8 );
|
||||
|
||||
/* Check stream properties */
|
||||
if( ac3_iec958_parse_syncinfo( p_spdif ) < 0 )
|
||||
{
|
||||
intf_ErrMsg( "spdif error: stream not valid");
|
||||
|
||||
aout_DestroyFifo( p_spdif->p_aout_fifo );
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
/* Check that we can handle the rate
|
||||
* FIXME: we should check that we have the same rate for all fifos
|
||||
* but all rates should be supported by the decoder (32, 44.1, 48) */
|
||||
if( p_spdif->ac3_info.i_sample_rate != 48000 )
|
||||
{
|
||||
intf_ErrMsg( "spdif error: Only 48000 Hz streams supported");
|
||||
|
||||
aout_DestroyFifo( p_spdif->p_aout_fifo );
|
||||
return -1;
|
||||
}
|
||||
p_spdif->p_aout_fifo->l_rate = p_spdif->ac3_info.i_sample_rate;
|
||||
|
||||
GetChunk( &p_spdif->bit_stream, p_spdif->p_ac3 + sizeof(sync_frame_t),
|
||||
p_spdif->ac3_info.i_frame_size - sizeof(sync_frame_t) );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* ErrorThread : ac3 spdif's RunThread() error loop
|
||||
* ac3_spdif_ErrorThread : ac3 spdif's RunThread() error loop
|
||||
*****************************************************************************/
|
||||
static void ErrorThread( ac3_spdif_thread_t * p_spdif )
|
||||
static void ac3_spdif_ErrorThread( ac3_spdif_thread_t * p_spdif )
|
||||
{
|
||||
/* We take the lock, because we are going to read/write the start/end
|
||||
* indexes of the decoder fifo */
|
||||
@ -303,9 +332,9 @@ static void ErrorThread( ac3_spdif_thread_t * p_spdif )
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* EndThread : ac3 spdif thread destruction
|
||||
* ac3_spdif_EndThread : ac3 spdif thread destruction
|
||||
*****************************************************************************/
|
||||
static void EndThread( ac3_spdif_thread_t * p_spdif )
|
||||
static void ac3_spdif_EndThread( ac3_spdif_thread_t * p_spdif )
|
||||
{
|
||||
intf_DbgMsg( "spdif debug: destroying thread %p", p_spdif );
|
||||
|
||||
@ -325,7 +354,7 @@ static void EndThread( ac3_spdif_thread_t * p_spdif )
|
||||
free( p_spdif->p_config );
|
||||
free( p_spdif->p_ac3 );
|
||||
free( p_spdif );
|
||||
|
||||
|
||||
intf_DbgMsg ("spdif debug: thread %p destroyed", p_spdif );
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ac3_spdif.h: header for ac3 pass-through
|
||||
*****************************************************************************
|
||||
* Copyright (C) 2001 VideoLAN
|
||||
* $Id: ac3_spdif.h,v 1.5 2001/09/30 20:25:13 bozo Exp $
|
||||
* $Id: ac3_spdif.h,v 1.1 2001/11/13 12:09:17 henri Exp $
|
||||
*
|
||||
* Authors: Stéphane Borel <stef@via.ecp.fr>
|
||||
*
|
||||
@ -43,7 +43,7 @@ typedef struct ac3_spdif_thread_s
|
||||
* Input properties
|
||||
*/
|
||||
decoder_fifo_t * p_fifo; /* stores the PES stream data */
|
||||
adec_config_t * p_config;
|
||||
decoder_config_t * p_config;
|
||||
|
||||
/* The bit stream structure handles the PES stream at the bit level */
|
||||
bit_stream_t bit_stream;
|
||||
@ -67,8 +67,3 @@ typedef struct ac3_spdif_thread_s
|
||||
|
||||
} ac3_spdif_thread_t;
|
||||
|
||||
/*****************************************************************************
|
||||
* Prototypes
|
||||
*****************************************************************************/
|
||||
vlc_thread_t spdif_CreateThread( adec_config_t * p_config );
|
||||
|
29
plugins/lpcm_adec/Makefile
Normal file
29
plugins/lpcm_adec/Makefile
Normal file
@ -0,0 +1,29 @@
|
||||
###############################################################################
|
||||
# vlc (VideoLAN Client) LPCM audio decoder module makefile
|
||||
# (c)2001 VideoLAN
|
||||
###############################################################################
|
||||
|
||||
#
|
||||
# Objects
|
||||
#
|
||||
PLUGIN_C = lpcm_adec.o
|
||||
BUILTIN_C = $(PLUGIN_C:%.o=BUILTIN_%.o)
|
||||
|
||||
ALL_OBJ = $(PLUGIN_C) $(BUILTIN_C)
|
||||
#
|
||||
# Virtual targets
|
||||
#
|
||||
|
||||
include ../../Makefile.modules
|
||||
|
||||
#
|
||||
# Real targets
|
||||
#
|
||||
|
||||
../lpcm_adec.so: $(PLUGIN_C)
|
||||
$(CC) $(PCFLAGS) -o $@ $^ $(PLCFLAGS)
|
||||
|
||||
../lpcm_adec.a: $(BUILTIN_C)
|
||||
ar r $@ $^
|
||||
$(RANLIB) $@
|
||||
|
@ -2,7 +2,7 @@
|
||||
* lpcm_decoder_thread.c: lpcm decoder thread
|
||||
*****************************************************************************
|
||||
* Copyright (C) 1999, 2000 VideoLAN
|
||||
* $Id: lpcm_decoder_thread.c,v 1.18 2001/11/06 18:13:21 massiot Exp $
|
||||
* $Id: lpcm_adec.c,v 1.1 2001/11/13 12:09:18 henri Exp $
|
||||
*
|
||||
* Authors: Samuel Hocevar <sam@zoy.org>
|
||||
* Henri Fallon <henri@videolan.org>
|
||||
@ -22,6 +22,9 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
|
||||
*****************************************************************************/
|
||||
|
||||
#define MODULE_NAME lpcm_adec
|
||||
#include "modules_inner.h"
|
||||
|
||||
/*****************************************************************************
|
||||
* Preamble
|
||||
*****************************************************************************/
|
||||
@ -39,79 +42,128 @@
|
||||
#include "common.h"
|
||||
#include "threads.h"
|
||||
#include "mtime.h"
|
||||
|
||||
#include "intf_msg.h" /* intf_DbgMsg(), intf_ErrMsg() */
|
||||
|
||||
#include "audio_output.h"
|
||||
|
||||
#include "modules.h"
|
||||
#include "modules_export.h"
|
||||
|
||||
#include "stream_control.h"
|
||||
#include "input_ext-dec.h"
|
||||
|
||||
#include "audio_output.h"
|
||||
|
||||
#include "lpcm_decoder_thread.h"
|
||||
#include "lpcm_adec.h"
|
||||
|
||||
/*****************************************************************************
|
||||
* Local prototypes
|
||||
*****************************************************************************/
|
||||
static int InitThread (lpcmdec_thread_t * p_adec);
|
||||
static void RunThread (lpcmdec_thread_t * p_adec);
|
||||
static void ErrorThread (lpcmdec_thread_t * p_adec);
|
||||
static void EndThread (lpcmdec_thread_t * p_adec);
|
||||
static int lpcm_adec_Probe ( probedata_t * );
|
||||
static int lpcm_adec_Run ( decoder_config_t * );
|
||||
void lpcm_adec_DecodeFrame ( lpcmdec_thread_t * );
|
||||
static int lpcm_adec_Init ( lpcmdec_thread_t * );
|
||||
static void lpcm_adec_ErrorThread ( lpcmdec_thread_t * );
|
||||
static void lpcm_adec_EndThread ( lpcmdec_thread_t * );
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* lpcmdec_CreateThread: creates an lpcm decoder thread
|
||||
* Capabilities
|
||||
*****************************************************************************/
|
||||
vlc_thread_t lpcmdec_CreateThread( adec_config_t * p_config )
|
||||
void _M( adec_getfunctions )( function_list_t * p_function_list )
|
||||
{
|
||||
p_function_list->pf_probe = lpcm_adec_Probe;
|
||||
p_function_list->functions.dec.pf_RunThread = lpcm_adec_Run;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* Build configuration tree.
|
||||
*****************************************************************************/
|
||||
MODULE_CONFIG_START
|
||||
ADD_WINDOW( "Configuration for lpcm audio decoder module" )
|
||||
ADD_COMMENT( "Nothing to configure" )
|
||||
MODULE_CONFIG_STOP
|
||||
|
||||
MODULE_INIT_START
|
||||
p_module->i_capabilities = MODULE_CAPABILITY_DEC;
|
||||
p_module->psz_longname = "Linear PCM audio decoder";
|
||||
MODULE_INIT_STOP
|
||||
|
||||
MODULE_ACTIVATE_START
|
||||
_M( adec_getfunctions )( &p_module->p_functions->dec );
|
||||
MODULE_ACTIVATE_STOP
|
||||
|
||||
MODULE_DEACTIVATE_START
|
||||
MODULE_DEACTIVATE_STOP
|
||||
|
||||
/*****************************************************************************
|
||||
* lpcm_adec_Probe: probe the decoder and return score
|
||||
*****************************************************************************/
|
||||
static int lpcm_adec_Probe( probedata_t *p_data )
|
||||
{
|
||||
if( p_data->i_type == LPCM_AUDIO_ES )
|
||||
return( 100 );
|
||||
else
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* lpcm_adec_Run: the lpcm decoder
|
||||
*****************************************************************************/
|
||||
static int lpcm_adec_Run( decoder_config_t * p_config )
|
||||
{
|
||||
lpcmdec_thread_t * p_lpcmdec;
|
||||
intf_DbgMsg( "LPCM: creating lpcm decoder thread" );
|
||||
|
||||
intf_DbgMsg("lpcm_adec debug: thread launched, initializing.");
|
||||
|
||||
/* Allocate the memory needed to store the thread's structure */
|
||||
if( (p_lpcmdec = (lpcmdec_thread_t *)malloc (sizeof(lpcmdec_thread_t)) )
|
||||
== NULL)
|
||||
{
|
||||
intf_ErrMsg( "LPCM : error : cannot create lpcmdec_thread_t" );
|
||||
return 0;
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize the thread properties
|
||||
*/
|
||||
p_lpcmdec->p_config = p_config;
|
||||
p_lpcmdec->p_fifo = p_config->decoder_config.p_decoder_fifo;
|
||||
p_lpcmdec->p_fifo = p_config->p_decoder_fifo;
|
||||
|
||||
/*
|
||||
* Initialize the output properties
|
||||
*/
|
||||
p_lpcmdec->p_aout_fifo = NULL;
|
||||
|
||||
/* Spawn the lpcm decoder thread */
|
||||
if( vlc_thread_create( &p_lpcmdec->thread_id, "lpcm decoder",
|
||||
(vlc_thread_func_t)RunThread, (void *)p_lpcmdec ) )
|
||||
if( lpcm_adec_Init( p_lpcmdec ) )
|
||||
{
|
||||
intf_ErrMsg( "LPCM : error : cannot spawn thread" );
|
||||
free (p_lpcmdec);
|
||||
return 0;
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
intf_DbgMsg( "LPCM Debug: lpcm decoder thread (%p) created\n", p_lpcmdec );
|
||||
return p_lpcmdec->thread_id;
|
||||
intf_DbgMsg( "LPCM Debug: lpcm decoder thread %p initialized\n",
|
||||
p_lpcmdec );
|
||||
|
||||
/* lpcm decoder thread's main loop */
|
||||
while ((!p_lpcmdec->p_fifo->b_die) && (!p_lpcmdec->p_fifo->b_error))
|
||||
{
|
||||
lpcm_adec_DecodeFrame(p_lpcmdec);
|
||||
}
|
||||
|
||||
/* If b_error is set, the lpcm decoder thread enters the error loop */
|
||||
if (p_lpcmdec->p_fifo->b_error)
|
||||
{
|
||||
lpcm_adec_ErrorThread (p_lpcmdec);
|
||||
}
|
||||
|
||||
/* End of the lpcm decoder thread */
|
||||
lpcm_adec_EndThread (p_lpcmdec);
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/* Following functions are local */
|
||||
|
||||
/*****************************************************************************
|
||||
* InitThread : initialize an lpcm decoder thread
|
||||
* lpcm_adec_Init : initialize an lpcm decoder thread
|
||||
*****************************************************************************/
|
||||
static int InitThread (lpcmdec_thread_t * p_lpcmdec)
|
||||
static int lpcm_adec_Init (lpcmdec_thread_t * p_lpcmdec)
|
||||
{
|
||||
|
||||
intf_DbgMsg ( "lpcm Debug: initializing lpcm decoder thread %p",
|
||||
p_lpcmdec );
|
||||
|
||||
/* Init the BitStream */
|
||||
p_lpcmdec->p_config->decoder_config.pf_init_bit_stream(
|
||||
p_lpcmdec->p_config->pf_init_bit_stream(
|
||||
&p_lpcmdec->bit_stream,
|
||||
p_lpcmdec->p_config->decoder_config.p_decoder_fifo,
|
||||
p_lpcmdec->p_config->p_decoder_fifo,
|
||||
NULL, NULL);
|
||||
|
||||
/* Creating the audio output fifo */
|
||||
@ -119,98 +171,73 @@ static int InitThread (lpcmdec_thread_t * p_lpcmdec)
|
||||
0, LPCMDEC_FRAME_SIZE/2, NULL );
|
||||
if ( p_lpcmdec->p_aout_fifo == NULL )
|
||||
{
|
||||
return -1;
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
intf_DbgMsg( "LPCM Debug: lpcm decoder thread %p initialized\n",
|
||||
p_lpcmdec );
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* RunThread : lpcm decoder thread
|
||||
* lpcm_adec_DecodeFrame: decodes a frame.
|
||||
*****************************************************************************/
|
||||
static void RunThread (lpcmdec_thread_t * p_lpcmdec)
|
||||
void lpcm_adec_DecodeFrame( lpcmdec_thread_t * p_lpcmdec )
|
||||
{
|
||||
intf_DbgMsg( "LPCM Debug: running lpcm decoder thread (%p) (pid== %i)",
|
||||
p_lpcmdec, getpid() );
|
||||
byte_t * buffer,p_temp[LPCMDEC_FRAME_SIZE];
|
||||
int i_loop;
|
||||
byte_t byte1, byte2;
|
||||
|
||||
/* Initializing the lpcm decoder thread */
|
||||
if (InitThread (p_lpcmdec))
|
||||
if( DECODER_FIFO_START(*p_lpcmdec->p_fifo)->i_pts )
|
||||
{
|
||||
p_lpcmdec->p_fifo->b_error = 1;
|
||||
p_lpcmdec->p_aout_fifo->date[p_lpcmdec->p_aout_fifo->l_end_frame] =
|
||||
DECODER_FIFO_START(*p_lpcmdec->p_fifo)->i_pts;
|
||||
DECODER_FIFO_START(*p_lpcmdec->p_fifo)->i_pts = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
p_lpcmdec->p_aout_fifo->date[p_lpcmdec->p_aout_fifo->l_end_frame] =
|
||||
LAST_MDATE;
|
||||
}
|
||||
|
||||
/* lpcm decoder thread's main loop */
|
||||
|
||||
while ((!p_lpcmdec->p_fifo->b_die) && (!p_lpcmdec->p_fifo->b_error))
|
||||
{
|
||||
byte_t * buffer,p_temp[LPCMDEC_FRAME_SIZE];
|
||||
int i_loop;
|
||||
byte_t byte1, byte2;
|
||||
buffer = ((byte_t *)p_lpcmdec->p_aout_fifo->buffer) +
|
||||
(p_lpcmdec->p_aout_fifo->l_end_frame * LPCMDEC_FRAME_SIZE);
|
||||
|
||||
RemoveBits32(&p_lpcmdec->bit_stream);
|
||||
byte1 = GetBits(&p_lpcmdec->bit_stream, 8) ;
|
||||
byte2 = GetBits(&p_lpcmdec->bit_stream, 8) ;
|
||||
|
||||
if( DECODER_FIFO_START(*p_lpcmdec->p_fifo)->i_pts )
|
||||
{
|
||||
p_lpcmdec->p_aout_fifo->date[p_lpcmdec->p_aout_fifo->l_end_frame] =
|
||||
DECODER_FIFO_START(*p_lpcmdec->p_fifo)->i_pts;
|
||||
DECODER_FIFO_START(*p_lpcmdec->p_fifo)->i_pts = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
p_lpcmdec->p_aout_fifo->date[p_lpcmdec->p_aout_fifo->l_end_frame] =
|
||||
LAST_MDATE;
|
||||
}
|
||||
|
||||
buffer = ((byte_t *)p_lpcmdec->p_aout_fifo->buffer) +
|
||||
(p_lpcmdec->p_aout_fifo->l_end_frame * LPCMDEC_FRAME_SIZE);
|
||||
|
||||
RemoveBits32(&p_lpcmdec->bit_stream);
|
||||
byte1 = GetBits(&p_lpcmdec->bit_stream, 8) ;
|
||||
byte2 = GetBits(&p_lpcmdec->bit_stream, 8) ;
|
||||
|
||||
/* I only have 2 test streams. As far as I understand
|
||||
* after the RemoveBits and the 2 GetBits, we should be exactly
|
||||
* where we whant : the sync word : 0x0180.
|
||||
* If not, we got and find it. */
|
||||
while( ( byte1 != 0x01 || byte2 != 0x80 ) && (!p_lpcmdec->p_fifo->b_die)
|
||||
&& (!p_lpcmdec->p_fifo->b_error) )
|
||||
{
|
||||
byte1 = byte2;
|
||||
byte2 = GetBits(&p_lpcmdec->bit_stream, 8);
|
||||
}
|
||||
|
||||
GetChunk( &p_lpcmdec->bit_stream, p_temp, LPCMDEC_FRAME_SIZE);
|
||||
|
||||
for( i_loop = 0; i_loop < LPCMDEC_FRAME_SIZE/2; i_loop++ )
|
||||
{
|
||||
buffer[2*i_loop]=p_temp[2*i_loop+1];
|
||||
buffer[2*i_loop+1]=p_temp[2*i_loop];
|
||||
}
|
||||
|
||||
vlc_mutex_lock (&p_lpcmdec->p_aout_fifo->data_lock);
|
||||
p_lpcmdec->p_aout_fifo->l_end_frame =
|
||||
(p_lpcmdec->p_aout_fifo->l_end_frame + 1) & AOUT_FIFO_SIZE;
|
||||
vlc_cond_signal (&p_lpcmdec->p_aout_fifo->data_wait);
|
||||
vlc_mutex_unlock (&p_lpcmdec->p_aout_fifo->data_lock);
|
||||
|
||||
intf_DbgMsg( "LPCM Debug: %x", *buffer );
|
||||
|
||||
}
|
||||
|
||||
/* If b_error is set, the lpcm decoder thread enters the error loop */
|
||||
if (p_lpcmdec->p_fifo->b_error)
|
||||
/* I only have 2 test streams. As far as I understand
|
||||
* after the RemoveBits and the 2 GetBits, we should be exactly
|
||||
* where we whant : the sync word : 0x0180.
|
||||
* If not, we got and find it. */
|
||||
while( ( byte1 != 0x01 || byte2 != 0x80 ) && (!p_lpcmdec->p_fifo->b_die)
|
||||
&& (!p_lpcmdec->p_fifo->b_error) )
|
||||
{
|
||||
ErrorThread (p_lpcmdec);
|
||||
byte1 = byte2;
|
||||
byte2 = GetBits(&p_lpcmdec->bit_stream, 8);
|
||||
}
|
||||
|
||||
GetChunk( &p_lpcmdec->bit_stream, p_temp, LPCMDEC_FRAME_SIZE);
|
||||
|
||||
for( i_loop = 0; i_loop < LPCMDEC_FRAME_SIZE/2; i_loop++ )
|
||||
{
|
||||
buffer[2*i_loop]=p_temp[2*i_loop+1];
|
||||
buffer[2*i_loop+1]=p_temp[2*i_loop];
|
||||
}
|
||||
|
||||
vlc_mutex_lock (&p_lpcmdec->p_aout_fifo->data_lock);
|
||||
p_lpcmdec->p_aout_fifo->l_end_frame =
|
||||
(p_lpcmdec->p_aout_fifo->l_end_frame + 1) & AOUT_FIFO_SIZE;
|
||||
vlc_cond_signal (&p_lpcmdec->p_aout_fifo->data_wait);
|
||||
vlc_mutex_unlock (&p_lpcmdec->p_aout_fifo->data_lock);
|
||||
|
||||
intf_DbgMsg( "LPCM Debug: %x", *buffer );
|
||||
|
||||
/* End of the lpcm decoder thread */
|
||||
EndThread (p_lpcmdec);
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* ErrorThread : lpcm decoder's RunThread() error loop
|
||||
* lpcm_adec_ErrorThread : lpcm decoder's RunThread() error loop
|
||||
*****************************************************************************/
|
||||
static void ErrorThread( lpcmdec_thread_t * p_lpcmdec )
|
||||
static void lpcm_adec_ErrorThread( lpcmdec_thread_t * p_lpcmdec )
|
||||
{
|
||||
/* We take the lock, because we are going to read/write the start/end
|
||||
* indexes of the decoder fifo */
|
||||
@ -237,9 +264,9 @@ static void ErrorThread( lpcmdec_thread_t * p_lpcmdec )
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* EndThread : lpcm decoder thread destruction
|
||||
* lpcm_adec_EndThread : lpcm decoder thread destruction
|
||||
*****************************************************************************/
|
||||
static void EndThread( lpcmdec_thread_t * p_lpcmdec )
|
||||
static void lpcm_adec_EndThread( lpcmdec_thread_t * p_lpcmdec )
|
||||
{
|
||||
intf_DbgMsg( "LPCM Debug: destroying lpcm decoder thread %p", p_lpcmdec );
|
||||
|
@ -2,7 +2,7 @@
|
||||
* lpcm_decoder_thread.h : lpcm decoder thread interface
|
||||
*****************************************************************************
|
||||
* Copyright (C) 1999, 2000 VideoLAN
|
||||
* $Id: lpcm_decoder_thread.h,v 1.7 2001/11/06 18:13:21 massiot Exp $
|
||||
* $Id: lpcm_adec.h,v 1.1 2001/11/13 12:09:18 henri Exp $
|
||||
*
|
||||
* Authors: Samuel Hocevar <sam@zoy.org>
|
||||
*
|
||||
@ -21,7 +21,6 @@
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*****************************************************************************/
|
||||
|
||||
#define LPCMDEC_FRAME_SIZE (2008)
|
||||
|
||||
/*****************************************************************************
|
||||
@ -39,7 +38,7 @@ typedef struct lpcmdec_thread_s
|
||||
*/
|
||||
decoder_fifo_t * p_fifo; /* stores the PES stream data */
|
||||
int sync_ptr; /* sync ptr from lpcm magic header */
|
||||
adec_config_t * p_config;
|
||||
decoder_config_t * p_config;
|
||||
|
||||
/*
|
||||
* Output properties
|
||||
@ -54,4 +53,4 @@ typedef struct lpcmdec_thread_s
|
||||
/*****************************************************************************
|
||||
* Prototypes
|
||||
*****************************************************************************/
|
||||
vlc_thread_t lpcmdec_CreateThread( adec_config_t * p_config );
|
||||
vlc_thread_t lpcmdec_CreateThread( decoder_config_t * p_config );
|
29
plugins/mpeg_adec/Makefile
Normal file
29
plugins/mpeg_adec/Makefile
Normal file
@ -0,0 +1,29 @@
|
||||
###############################################################################
|
||||
# vlc (VideoLAN Client) MPEG audio decoder module makefile
|
||||
# (c)2001 VideoLAN
|
||||
###############################################################################
|
||||
|
||||
#
|
||||
# Objects
|
||||
#
|
||||
PLUGIN_C = mpeg_adec.o adec_layer1.o adec_layer2.o adec_math.o mpeg_adec_generic.o
|
||||
BUILTIN_C = $(PLUGIN_C:%.o=BUILTIN_%.o)
|
||||
|
||||
ALL_OBJ = $(PLUGIN_C) $(BUILTIN_C)
|
||||
#
|
||||
# Virtual targets
|
||||
#
|
||||
|
||||
include ../../Makefile.modules
|
||||
|
||||
#
|
||||
# Real targets
|
||||
#
|
||||
|
||||
../mpeg_adec.so: $(PLUGIN_C)
|
||||
$(CC) $(PCFLAGS) -o $@ $^ $(PLCFLAGS)
|
||||
|
||||
../mpeg_adec.a: $(BUILTIN_C)
|
||||
ar r $@ $^
|
||||
$(RANLIB) $@
|
||||
|
@ -2,7 +2,7 @@
|
||||
* adec_layer1.c: MPEG Layer I audio decoder
|
||||
*****************************************************************************
|
||||
* Copyright (C) 1999, 2000 VideoLAN
|
||||
* $Id: adec_layer1.c,v 1.5 2001/04/12 01:52:45 sam Exp $
|
||||
* $Id: adec_layer1.c,v 1.1 2001/11/13 12:09:18 henri Exp $
|
||||
*
|
||||
* Authors: Michel Kaempf <maxx@via.ecp.fr>
|
||||
* Michel Lespinasse <walken@via.ecp.fr>
|
||||
@ -38,11 +38,13 @@
|
||||
#include "common.h"
|
||||
#include "threads.h"
|
||||
#include "mtime.h"
|
||||
|
||||
#include "modules_export.h"
|
||||
#include "stream_control.h"
|
||||
#include "input_ext-dec.h"
|
||||
|
||||
#include "adec_generic.h"
|
||||
#include "audio_decoder.h"
|
||||
#include "mpeg_adec_generic.h"
|
||||
#include "mpeg_adec.h"
|
||||
#include "adec_math.h" /* DCT32(), PCM() */
|
||||
|
||||
/**** wkn ****/
|
@ -2,7 +2,7 @@
|
||||
* adec_layer1.h: MPEG Layer I audio decoder
|
||||
*****************************************************************************
|
||||
* Copyright (C) 1999, 2000 VideoLAN
|
||||
* $Id: adec_layer1.h,v 1.3 2001/03/21 13:42:34 sam Exp $
|
||||
* $Id: adec_layer1.h,v 1.1 2001/11/13 12:09:18 henri Exp $
|
||||
*
|
||||
* Authors: Michel Kaempf <maxx@via.ecp.fr>
|
||||
*
|
@ -2,7 +2,7 @@
|
||||
* adec_layer2.c: MPEG Layer II audio decoder
|
||||
*****************************************************************************
|
||||
* Copyright (C) 1999, 2000 VideoLAN
|
||||
* $Id: adec_layer2.c,v 1.5 2001/04/12 01:52:45 sam Exp $
|
||||
* $Id: adec_layer2.c,v 1.1 2001/11/13 12:09:18 henri Exp $
|
||||
*
|
||||
* Authors: Michel Kaempf <maxx@via.ecp.fr>
|
||||
* Michel Lespinasse <walken@via.ecp.fr>
|
||||
@ -38,11 +38,12 @@
|
||||
#include "common.h"
|
||||
#include "threads.h"
|
||||
#include "mtime.h"
|
||||
#include "modules_export.h"
|
||||
#include "stream_control.h"
|
||||
#include "input_ext-dec.h"
|
||||
|
||||
#include "adec_generic.h"
|
||||
#include "audio_decoder.h"
|
||||
#include "mpeg_adec_generic.h"
|
||||
#include "mpeg_adec.h"
|
||||
#include "adec_math.h" /* DCT32(), PCM() */
|
||||
|
||||
/**** wkn ****/
|
@ -2,7 +2,7 @@
|
||||
* adec_layer2.h: MPEG Layer II audio decoder
|
||||
*****************************************************************************
|
||||
* Copyright (C) 1999, 2000 VideoLAN
|
||||
* $Id: adec_layer2.h,v 1.3 2001/03/21 13:42:34 sam Exp $
|
||||
* $Id: adec_layer2.h,v 1.1 2001/11/13 12:09:18 henri Exp $
|
||||
*
|
||||
* Authors: Michel Kaempf <maxx@via.ecp.fr>
|
||||
*
|
@ -2,7 +2,7 @@
|
||||
* adec_math.c: Inverse Discrete Cosine Transform and Pulse Code Modulation
|
||||
*****************************************************************************
|
||||
* Copyright (C) 1999, 2000 VideoLAN
|
||||
* $Id: adec_math.c,v 1.3 2001/03/21 13:42:34 sam Exp $
|
||||
* $Id: adec_math.c,v 1.1 2001/11/13 12:09:18 henri Exp $
|
||||
*
|
||||
* Authors: Michel Kaempf <maxx@via.ecp.fr>
|
||||
* Michel Lespinasse <walken@via.ecp.fr>
|
||||
@ -23,7 +23,7 @@
|
||||
*****************************************************************************/
|
||||
|
||||
#include "int_types.h"
|
||||
#include "adec_generic.h"
|
||||
#include "mpeg_adec_generic.h"
|
||||
|
||||
/*****************************************************************************
|
||||
* DCT32: Fast 32 points Discrete Cosine Transform
|
@ -2,7 +2,7 @@
|
||||
* adec_math.h : PCM and DCT
|
||||
*****************************************************************************
|
||||
* Copyright (C) 1999, 2000 VideoLAN
|
||||
* $Id: adec_math.h,v 1.2 2001/03/21 13:42:34 sam Exp $
|
||||
* $Id: adec_math.h,v 1.1 2001/11/13 12:09:18 henri Exp $
|
||||
*
|
||||
* Authors: Michel Kaempf <maxx@via.ecp.fr>
|
||||
*
|
@ -2,7 +2,7 @@
|
||||
* adec_test.c: MPEG Layer I-II audio decoder test program
|
||||
*****************************************************************************
|
||||
* Copyright (C) 1999, 2000 VideoLAN
|
||||
* $Id: adec_test.c,v 1.4 2001/03/21 13:42:34 sam Exp $
|
||||
* $Id: adec_test.c,v 1.1 2001/11/13 12:09:18 henri Exp $
|
||||
*
|
||||
* Authors: Michel Kaempf <maxx@via.ecp.fr>
|
||||
* Michel Lespinasse <walken@via.ecp.fr>
|
||||
@ -38,8 +38,8 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "int_types.h"
|
||||
#include "adec_generic.h"
|
||||
#include "audio_decoder.h"
|
||||
#include "mpeg_adec_generic.h"
|
||||
#include "mpeg_adec.h"
|
||||
|
||||
#define ADEC_FRAME_SIZE (2*1152)
|
||||
|
@ -1,8 +1,8 @@
|
||||
/*****************************************************************************
|
||||
* audio_decoder.c: MPEG audio decoder thread
|
||||
* mpeg_adec.c: MPEG audio decoder thread
|
||||
*****************************************************************************
|
||||
* Copyright (C) 1999, 2000 VideoLAN
|
||||
* $Id: audio_decoder.c,v 1.52 2001/08/22 17:21:45 massiot Exp $
|
||||
* $Id: mpeg_adec.c,v 1.1 2001/11/13 12:09:18 henri Exp $
|
||||
*
|
||||
* Authors: Michel Kaempf <maxx@via.ecp.fr>
|
||||
* Michel Lespinasse <walken@via.ecp.fr>
|
||||
@ -23,65 +23,94 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
|
||||
*****************************************************************************/
|
||||
|
||||
/*
|
||||
* TODO :
|
||||
*
|
||||
* - optimiser les NeedBits() et les GetBits() du code là où c'est possible ;
|
||||
* - vlc_cond_signal() / vlc_cond_wait() ;
|
||||
*
|
||||
*/
|
||||
#define MODULE_NAME mpeg_adec
|
||||
#include "modules_inner.h"
|
||||
|
||||
/*****************************************************************************
|
||||
* Preamble
|
||||
*****************************************************************************/
|
||||
#include "defs.h"
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h> /* getpid() */
|
||||
#endif
|
||||
|
||||
#include <stdio.h> /* "intf_msg.h" */
|
||||
#include <string.h> /* memcpy(), memset() */
|
||||
#include <stdlib.h> /* malloc(), free() */
|
||||
|
||||
#include "config.h"
|
||||
#include "common.h"
|
||||
#include "common.h" /* boolean_t, byte_t */
|
||||
#include "threads.h"
|
||||
#include "mtime.h"
|
||||
|
||||
#include "intf_msg.h" /* intf_DbgMsg(), intf_ErrMsg() */
|
||||
|
||||
#include "stream_control.h"
|
||||
#include "input_ext-dec.h"
|
||||
#include "intf_msg.h"
|
||||
|
||||
#include "audio_output.h" /* aout_fifo_t (for audio_decoder.h) */
|
||||
|
||||
#include "adec_generic.h"
|
||||
#include "audio_decoder.h"
|
||||
#include "adec_math.h" /* DCT32(), PCM() */
|
||||
#include "modules.h"
|
||||
#include "modules_export.h"
|
||||
|
||||
#include "stream_control.h"
|
||||
#include "input_ext-dec.h"
|
||||
|
||||
#include "mpeg_adec_generic.h"
|
||||
#include "mpeg_adec.h"
|
||||
|
||||
#define ADEC_FRAME_SIZE (2*1152)
|
||||
|
||||
/*****************************************************************************
|
||||
* Local prototypes
|
||||
* 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_Probe( probedata_t * );
|
||||
static int adec_RunThread ( decoder_config_t * );
|
||||
static void adec_EndThread ( adec_thread_t * );
|
||||
static void adec_ErrorThread ( adec_thread_t * );
|
||||
static void adec_Decode( adec_thread_t * );
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* 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.
|
||||
* Capabilities
|
||||
*****************************************************************************/
|
||||
vlc_thread_t adec_CreateThread ( adec_config_t * p_config )
|
||||
void _M( adec_getfunctions )( function_list_t * p_function_list )
|
||||
{
|
||||
adec_thread_t * p_adec;
|
||||
p_function_list->pf_probe = adec_Probe;
|
||||
p_function_list->functions.dec.pf_RunThread = adec_RunThread;
|
||||
}
|
||||
|
||||
intf_DbgMsg ( "adec debug: creating audio decoder thread" );
|
||||
/*****************************************************************************
|
||||
* Build configuration tree.
|
||||
*****************************************************************************/
|
||||
MODULE_CONFIG_START
|
||||
ADD_WINDOW( "Configuration for mpeg audio decoder module" )
|
||||
ADD_COMMENT( "Nothing to configure" )
|
||||
MODULE_CONFIG_STOP
|
||||
|
||||
MODULE_INIT_START
|
||||
p_module->i_capabilities = MODULE_CAPABILITY_DEC;
|
||||
p_module->psz_longname = "Mpeg I layer 1/2 audio decoder";
|
||||
MODULE_INIT_STOP
|
||||
|
||||
MODULE_ACTIVATE_START
|
||||
_M( adec_getfunctions )( &p_module->p_functions->dec );
|
||||
MODULE_ACTIVATE_STOP
|
||||
|
||||
MODULE_DEACTIVATE_START
|
||||
MODULE_DEACTIVATE_STOP
|
||||
|
||||
/*****************************************************************************
|
||||
* adec_Probe: probe the decoder and return score
|
||||
*****************************************************************************/
|
||||
static int adec_Probe( probedata_t *p_data )
|
||||
{
|
||||
if( p_data->i_type == MPEG1_AUDIO_ES || p_data->i_type == MPEG2_AUDIO_ES )
|
||||
return( 100 );
|
||||
else
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* adec_RunThread: initialize, go inside main loop, detroy
|
||||
*****************************************************************************/
|
||||
static int adec_RunThread ( decoder_config_t * p_config )
|
||||
{
|
||||
adec_thread_t * p_adec;
|
||||
|
||||
intf_DbgMsg("mpeg_adec debug: thread launched, initializing.");
|
||||
|
||||
/* Allocate the memory needed to store the thread's structure */
|
||||
if ( (p_adec = (adec_thread_t *)malloc (sizeof(adec_thread_t))) == NULL )
|
||||
{
|
||||
@ -89,143 +118,116 @@ vlc_thread_t adec_CreateThread ( adec_config_t * p_config )
|
||||
" adec_CreateThread() to create the new thread" );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Initialize the thread properties
|
||||
*/
|
||||
p_adec->p_config = p_config;
|
||||
p_adec->p_fifo = p_config->decoder_config.p_decoder_fifo;
|
||||
p_adec->p_fifo = p_config->p_decoder_fifo;
|
||||
|
||||
/*
|
||||
* Initialize the decoder properties
|
||||
/*
|
||||
* Initilize the banks
|
||||
*/
|
||||
adec_Init ( p_adec );
|
||||
|
||||
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
|
||||
* Initialize bit stream
|
||||
*/
|
||||
p_adec->p_aout_fifo = NULL;
|
||||
p_adec->p_config->pf_init_bit_stream( &p_adec->bit_stream,
|
||||
p_adec->p_config->p_decoder_fifo, NULL, 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");
|
||||
free (p_adec);
|
||||
return 0;
|
||||
}
|
||||
|
||||
intf_DbgMsg ("adec debug: audio decoder thread (%p) created", p_adec);
|
||||
return p_adec->thread_id;
|
||||
}
|
||||
|
||||
/* following functions are local */
|
||||
|
||||
/*****************************************************************************
|
||||
* 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)
|
||||
{
|
||||
intf_DbgMsg ("adec debug: initializing audio decoder thread %p", p_adec);
|
||||
|
||||
p_adec->p_config->decoder_config.pf_init_bit_stream( &p_adec->bit_stream,
|
||||
p_adec->p_config->decoder_config.p_decoder_fifo, NULL, NULL );
|
||||
|
||||
/* Creating the audio output fifo */
|
||||
/* Create the audio output fifo */
|
||||
p_adec->p_aout_fifo = aout_CreateFifo( AOUT_ADEC_STEREO_FIFO, 2, 0, 0,
|
||||
ADEC_FRAME_SIZE, NULL );
|
||||
if ( p_adec->p_aout_fifo == NULL )
|
||||
if ( p_adec->p_aout_fifo == NULL )
|
||||
{
|
||||
intf_ErrMsg("mpeg_adec error: cannot create audio output fifo");
|
||||
return -1;
|
||||
}
|
||||
|
||||
intf_DbgMsg ( "adec debug: audio decoder thread %p initialized", p_adec );
|
||||
return 0;
|
||||
}
|
||||
intf_DbgMsg("mpeg_adec debug: thread initialized, decoding begins.");
|
||||
|
||||
/*****************************************************************************
|
||||
* 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)",
|
||||
p_adec, getpid() );
|
||||
|
||||
/* Initializing the audio decoder thread */
|
||||
p_adec->p_fifo->b_error = InitThread (p_adec);
|
||||
|
||||
sync = 0;
|
||||
p_adec->i_sync = 0;
|
||||
|
||||
/* Audio decoder thread's main loop */
|
||||
while( (!p_adec->p_fifo->b_die) && (!p_adec->p_fifo->b_error) )
|
||||
{
|
||||
s16 * buffer;
|
||||
adec_sync_info_t sync_info;
|
||||
|
||||
if( ! adec_SyncFrame (p_adec, &sync_info) )
|
||||
{
|
||||
sync = 1;
|
||||
|
||||
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( DECODER_FIFO_START( *p_adec->p_fifo)->i_pts )
|
||||
{
|
||||
p_adec->p_aout_fifo->date[p_adec->p_aout_fifo->l_end_frame] =
|
||||
DECODER_FIFO_START( *p_adec->p_fifo )->i_pts;
|
||||
DECODER_FIFO_START(*p_adec->p_fifo)->i_pts = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
p_adec->p_aout_fifo->date[p_adec->p_aout_fifo->l_end_frame] =
|
||||
LAST_MDATE;
|
||||
}
|
||||
|
||||
if( adec_DecodeFrame (p_adec, buffer) )
|
||||
{
|
||||
/* Ouch, failed decoding... We'll have to resync */
|
||||
sync = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
vlc_mutex_lock (&p_adec->p_aout_fifo->data_lock);
|
||||
|
||||
p_adec->p_aout_fifo->l_end_frame =
|
||||
(p_adec->p_aout_fifo->l_end_frame + 1) & AOUT_FIFO_SIZE;
|
||||
vlc_cond_signal (&p_adec->p_aout_fifo->data_wait);
|
||||
vlc_mutex_unlock (&p_adec->p_aout_fifo->data_lock);
|
||||
}
|
||||
}
|
||||
adec_Decode( p_adec );
|
||||
}
|
||||
|
||||
|
||||
/* If b_error is set, the audio decoder thread enters the error loop */
|
||||
if( p_adec->p_fifo->b_error )
|
||||
{
|
||||
ErrorThread( p_adec );
|
||||
adec_ErrorThread( p_adec );
|
||||
}
|
||||
|
||||
/* End of the audio decoder thread */
|
||||
EndThread( p_adec );
|
||||
adec_EndThread( p_adec );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/*
|
||||
* Following finctions are local to this module
|
||||
*/
|
||||
|
||||
/*****************************************************************************
|
||||
* adec_Decode: decodes a mpeg frame
|
||||
*****************************************************************************/
|
||||
static void adec_Decode( adec_thread_t * p_adec )
|
||||
{
|
||||
s16 * buffer;
|
||||
adec_sync_info_t sync_info;
|
||||
|
||||
if( ! adec_SyncFrame (p_adec, &sync_info) )
|
||||
{
|
||||
p_adec->i_sync = 1;
|
||||
|
||||
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( DECODER_FIFO_START( *p_adec->p_fifo)->i_pts )
|
||||
{
|
||||
p_adec->p_aout_fifo->date[p_adec->p_aout_fifo->l_end_frame] =
|
||||
DECODER_FIFO_START( *p_adec->p_fifo )->i_pts;
|
||||
DECODER_FIFO_START(*p_adec->p_fifo)->i_pts = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
p_adec->p_aout_fifo->date[p_adec->p_aout_fifo->l_end_frame] =
|
||||
LAST_MDATE;
|
||||
}
|
||||
|
||||
if( adec_DecodeFrame (p_adec, buffer) )
|
||||
{
|
||||
/* Ouch, failed decoding... We'll have to resync */
|
||||
p_adec->i_sync = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
vlc_mutex_lock (&p_adec->p_aout_fifo->data_lock);
|
||||
|
||||
p_adec->p_aout_fifo->l_end_frame =
|
||||
(p_adec->p_aout_fifo->l_end_frame + 1) & AOUT_FIFO_SIZE;
|
||||
vlc_cond_signal (&p_adec->p_aout_fifo->data_wait);
|
||||
vlc_mutex_unlock (&p_adec->p_aout_fifo->data_lock);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* ErrorThread : audio decoder's RunThread() error loop
|
||||
* adec_ErrorThread : audio decoder's RunThread() error loop
|
||||
*****************************************************************************
|
||||
* This function is called when an error occured during thread main's loop. The
|
||||
* thread can still receive feed, but must be ready to terminate as soon as
|
||||
* possible.
|
||||
*****************************************************************************/
|
||||
static void ErrorThread ( adec_thread_t *p_adec )
|
||||
static void adec_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 */
|
||||
@ -250,13 +252,14 @@ static void ErrorThread ( adec_thread_t *p_adec )
|
||||
vlc_mutex_unlock ( &p_adec->p_fifo->data_lock );
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* EndThread : audio decoder thread destruction
|
||||
* adec_EndThread : audio decoder thread destruction
|
||||
*****************************************************************************
|
||||
* This function is called when the thread ends after a sucessful
|
||||
* initialization.
|
||||
*****************************************************************************/
|
||||
static void EndThread ( adec_thread_t *p_adec )
|
||||
static void adec_EndThread ( adec_thread_t *p_adec )
|
||||
{
|
||||
intf_DbgMsg ( "adec debug: destroying audio decoder thread %p", p_adec );
|
||||
|
@ -1,8 +1,8 @@
|
||||
/*****************************************************************************
|
||||
* audio_decoder.h : audio decoder thread interface
|
||||
* mpeg_adec.h : audio decoder thread interface
|
||||
*****************************************************************************
|
||||
* Copyright (C) 1999, 2000 VideoLAN
|
||||
* $Id: audio_decoder.h,v 1.7 2001/05/01 04:18:18 sam Exp $
|
||||
* $Id: mpeg_adec.h,v 1.1 2001/11/13 12:09:18 henri Exp $
|
||||
*
|
||||
* Authors: Michel Kaempf <maxx@via.ecp.fr>
|
||||
*
|
||||
@ -26,11 +26,10 @@
|
||||
*****************************************************************************/
|
||||
typedef struct adec_thread_s
|
||||
{
|
||||
/*
|
||||
* Thread properties
|
||||
/*
|
||||
* Sync Information
|
||||
*/
|
||||
vlc_thread_t thread_id; /* id for thread functions */
|
||||
|
||||
int i_sync;
|
||||
/*
|
||||
* Input properties
|
||||
*/
|
||||
@ -38,7 +37,7 @@ typedef struct adec_thread_s
|
||||
/* The bit stream structure handles the PES stream at the bit level */
|
||||
bit_stream_t bit_stream;
|
||||
int i_read_bits;
|
||||
adec_config_t * p_config;
|
||||
decoder_config_t * p_config;
|
||||
|
||||
/*
|
||||
* Decoder properties
|
||||
@ -58,9 +57,9 @@ typedef struct adec_thread_s
|
||||
/*****************************************************************************
|
||||
* Prototypes
|
||||
*****************************************************************************/
|
||||
vlc_thread_t adec_CreateThread ( adec_config_t * p_config );
|
||||
int adec_Init ( adec_thread_t * p_adec );
|
||||
int adec_SyncFrame ( adec_thread_t * p_adec,
|
||||
adec_sync_info_t * p_sync_info );
|
||||
int adec_DecodeFrame ( adec_thread_t * p_adec, s16 * buffer );
|
||||
|
||||
/*
|
||||
* From adec_generic.c
|
||||
*/
|
||||
int adec_SyncFrame( adec_thread_t *, adec_sync_info_t * );
|
||||
int adec_DecodeFrame( adec_thread_t * , s16 * );
|
@ -2,7 +2,7 @@
|
||||
* adec_generic.c: MPEG audio decoder
|
||||
*****************************************************************************
|
||||
* Copyright (C) 1999, 2000 VideoLAN
|
||||
* $Id: adec_generic.c,v 1.6 2001/09/05 16:46:10 massiot Exp $
|
||||
* $Id: mpeg_adec_generic.c,v 1.1 2001/11/13 12:09:18 henri Exp $
|
||||
*
|
||||
* Authors: Michel Kaempf <maxx@via.ecp.fr>
|
||||
* Michel Lespinasse <walken@via.ecp.fr>
|
||||
@ -30,11 +30,15 @@
|
||||
#include "common.h"
|
||||
#include "threads.h"
|
||||
#include "mtime.h"
|
||||
#include "stream_control.h"
|
||||
#include "input_ext-dec.h"
|
||||
|
||||
#include "adec_generic.h"
|
||||
#include "audio_decoder.h"
|
||||
#include "modules.h"
|
||||
#include "modules_export.h" /* Used for exporting vlc symbols to plugins */
|
||||
|
||||
#include "input_ext-dec.h"
|
||||
#include "stream_control.h"
|
||||
|
||||
#include "mpeg_adec_generic.h"
|
||||
#include "mpeg_adec.h"
|
||||
#include "adec_math.h" /* DCT32(), PCM() */
|
||||
#include "adec_layer1.h"
|
||||
#include "adec_layer2.h"
|
@ -2,7 +2,7 @@
|
||||
* audio_decoder.h : audio decoder interface
|
||||
*****************************************************************************
|
||||
* Copyright (C) 1999, 2000 VideoLAN
|
||||
* $Id: adec_generic.h,v 1.4 2001/03/21 13:42:34 sam Exp $
|
||||
* $Id: mpeg_adec_generic.h,v 1.1 2001/11/13 12:09:18 henri Exp $
|
||||
*
|
||||
* Authors: Michel Kaempf <maxx@via.ecp.fr>
|
||||
*
|
||||
@ -40,3 +40,4 @@ typedef struct adec_bank_s
|
||||
|
||||
} adec_bank_t;
|
||||
|
||||
|
29
plugins/mpeg_vdec/Makefile
Normal file
29
plugins/mpeg_vdec/Makefile
Normal file
@ -0,0 +1,29 @@
|
||||
###############################################################################
|
||||
# vlc (VideoLAN Client) MPEG audio decoder module makefile
|
||||
# (c)2001 VideoLAN
|
||||
###############################################################################
|
||||
|
||||
#
|
||||
# Objects
|
||||
#
|
||||
PLUGIN_C = video_parser.o vpar_headers.o vpar_blocks.o vpar_synchro.o vpar_pool.o video_decoder.o
|
||||
BUILTIN_C = $(PLUGIN_C:%.o=BUILTIN_%.o)
|
||||
|
||||
ALL_OBJ = $(PLUGIN_C) $(BUILTIN_C)
|
||||
#
|
||||
# Virtual targets
|
||||
#
|
||||
|
||||
include ../../Makefile.modules
|
||||
|
||||
#
|
||||
# Real targets
|
||||
#
|
||||
|
||||
../mpeg_vdec.so: $(PLUGIN_C)
|
||||
$(CC) $(PCFLAGS) -o $@ $^ $(PLCFLAGS)
|
||||
|
||||
../mpeg_vdec.a: $(BUILTIN_C)
|
||||
ar r $@ $^
|
||||
$(RANLIB) $@
|
||||
|
@ -2,7 +2,7 @@
|
||||
* video_decoder.c : video decoder thread
|
||||
*****************************************************************************
|
||||
* Copyright (C) 1999, 2000 VideoLAN
|
||||
* $Id: video_decoder.c,v 1.60 2001/10/11 16:12:43 massiot Exp $
|
||||
* $Id: video_decoder.c,v 1.1 2001/11/13 12:09:18 henri Exp $
|
||||
*
|
||||
* Authors: Christophe Massiot <massiot@via.ecp.fr>
|
||||
* Michel Lespinasse <walken@zoy.org>
|
||||
@ -39,15 +39,15 @@
|
||||
#include "common.h"
|
||||
#include "threads.h"
|
||||
#include "mtime.h"
|
||||
|
||||
#include "intf_msg.h"
|
||||
|
||||
#include "stream_control.h"
|
||||
#include "input_ext-dec.h"
|
||||
|
||||
#include "video.h"
|
||||
#include "video_output.h"
|
||||
|
||||
#include "modules_export.h"
|
||||
#include "stream_control.h"
|
||||
#include "input_ext-dec.h"
|
||||
|
||||
#include "vdec_ext-plugins.h"
|
||||
#include "video_decoder.h"
|
||||
#include "vpar_pool.h"
|
@ -2,7 +2,7 @@
|
||||
* video_decoder.h : video decoder thread
|
||||
*****************************************************************************
|
||||
* Copyright (C) 1999, 2000 VideoLAN
|
||||
* $Id: video_decoder.h,v 1.6 2001/10/11 13:19:27 massiot Exp $
|
||||
* $Id: video_decoder.h,v 1.1 2001/11/13 12:09:18 henri Exp $
|
||||
*
|
||||
* Authors: Christophe Massiot <massiot@via.ecp.fr>
|
||||
*
|
@ -2,7 +2,7 @@
|
||||
* video_parser.c : video parser thread
|
||||
*****************************************************************************
|
||||
* Copyright (C) 1999, 2000 VideoLAN
|
||||
* $Id: video_parser.c,v 1.8 2001/10/03 13:14:05 sam Exp $
|
||||
* $Id: video_parser.c,v 1.1 2001/11/13 12:09:18 henri Exp $
|
||||
*
|
||||
* Authors: Christophe Massiot <massiot@via.ecp.fr>
|
||||
* Samuel Hocevar <sam@via.ecp.fr>
|
||||
@ -22,6 +22,9 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
|
||||
*****************************************************************************/
|
||||
|
||||
#define MODULE_NAME mpeg_vdec
|
||||
#include "modules_inner.h"
|
||||
|
||||
/*****************************************************************************
|
||||
* Preamble
|
||||
*****************************************************************************/
|
||||
@ -45,85 +48,157 @@
|
||||
#include "threads.h"
|
||||
#include "mtime.h"
|
||||
#include "modules.h"
|
||||
|
||||
#include "intf_msg.h"
|
||||
|
||||
#include "stream_control.h"
|
||||
#include "input_ext-dec.h"
|
||||
#include "main.h"
|
||||
|
||||
#include "video.h"
|
||||
#include "video_output.h"
|
||||
|
||||
#include "modules_export.h"
|
||||
#include "stream_control.h"
|
||||
#include "input_ext-dec.h"
|
||||
|
||||
|
||||
#include "vdec_ext-plugins.h"
|
||||
#include "vpar_pool.h"
|
||||
#include "video_parser.h"
|
||||
|
||||
#include "main.h"
|
||||
|
||||
/*
|
||||
* Local prototypes
|
||||
*/
|
||||
static int InitThread ( vpar_thread_t * );
|
||||
static void RunThread ( vpar_thread_t * );
|
||||
static void ErrorThread ( vpar_thread_t * );
|
||||
static void EndThread ( vpar_thread_t * );
|
||||
static void BitstreamCallback ( bit_stream_t *, boolean_t );
|
||||
static int mpeg_vdec_Probe ( probedata_t * );
|
||||
static int mpeg_vdec_Run ( decoder_config_t * );
|
||||
static int mpeg_vdec_Init ( vpar_thread_t * );
|
||||
static void mpeg_vdec_ErrorThread ( vpar_thread_t * );
|
||||
static void mpeg_vdec_EndThread ( vpar_thread_t * );
|
||||
static void BitstreamCallback ( bit_stream_t *, boolean_t );
|
||||
|
||||
/*****************************************************************************
|
||||
* vpar_CreateThread: create a generic parser thread
|
||||
*****************************************************************************
|
||||
* This function creates a new video parser thread, and returns a pointer
|
||||
* to its description. On error, it returns NULL.
|
||||
* Capabilities
|
||||
*****************************************************************************/
|
||||
vlc_thread_t vpar_CreateThread( vdec_config_t * p_config )
|
||||
void _M( vdec_getfunctions )( function_list_t * p_function_list )
|
||||
{
|
||||
p_function_list->pf_probe = mpeg_vdec_Probe;
|
||||
p_function_list->functions.dec.pf_RunThread = mpeg_vdec_Run;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* Build configuration tree.
|
||||
*****************************************************************************/
|
||||
MODULE_CONFIG_START
|
||||
ADD_WINDOW( "Configuration for MPEG video decoder module" )
|
||||
ADD_COMMENT( "Nothing to configure" )
|
||||
MODULE_CONFIG_STOP
|
||||
|
||||
MODULE_INIT_START
|
||||
p_module->i_capabilities = MODULE_CAPABILITY_DEC;
|
||||
p_module->psz_longname = "MPEG I/II video decoder module";
|
||||
MODULE_INIT_STOP
|
||||
|
||||
MODULE_ACTIVATE_START
|
||||
_M( vdec_getfunctions )( &p_module->p_functions->dec );
|
||||
MODULE_ACTIVATE_STOP
|
||||
|
||||
MODULE_DEACTIVATE_START
|
||||
MODULE_DEACTIVATE_STOP
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* mpeg_vdec_Probe: probe the decoder and return score
|
||||
*****************************************************************************
|
||||
* Tries to launch a decoder and return score so that the interface is able
|
||||
* to chose.
|
||||
*****************************************************************************/
|
||||
static int mpeg_vdec_Probe( probedata_t *p_data )
|
||||
{
|
||||
if( p_data->i_type == MPEG1_VIDEO_ES || p_data->i_type == MPEG2_VIDEO_ES )
|
||||
return( 50 );
|
||||
else
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* mpeg_vdec_Run: this function is called just after the thread is created
|
||||
*****************************************************************************/
|
||||
static int mpeg_vdec_Run ( decoder_config_t * p_config )
|
||||
{
|
||||
vpar_thread_t * p_vpar;
|
||||
|
||||
intf_DbgMsg( "vpar debug: creating video parser thread" );
|
||||
intf_DbgMsg( "vpar debug: video parser thread created. Initializing..." );
|
||||
|
||||
/* Allocate the memory needed to store the thread's structure */
|
||||
if ( (p_vpar = (vpar_thread_t *)malloc( sizeof(vpar_thread_t) )) == NULL )
|
||||
{
|
||||
intf_ErrMsg( "vpar error: not enough memory "
|
||||
"for vpar_CreateThread() to create the new thread");
|
||||
return( 0 );
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize the thread properties
|
||||
*/
|
||||
p_vpar->p_fifo = p_config->decoder_config.p_decoder_fifo;
|
||||
p_vpar->p_fifo = p_config->p_decoder_fifo;
|
||||
p_vpar->p_config = p_config;
|
||||
p_vpar->p_vout = NULL;
|
||||
|
||||
/* Spawn the video parser thread */
|
||||
if ( vlc_thread_create( &p_vpar->thread_id, "video parser",
|
||||
(vlc_thread_func_t)RunThread, (void *)p_vpar ) )
|
||||
/*
|
||||
* Initialize thread
|
||||
*/
|
||||
p_vpar->p_fifo->b_error = mpeg_vdec_Init( p_vpar );
|
||||
|
||||
/*
|
||||
* Main loop - it is not executed if an error occured during
|
||||
* initialization
|
||||
*/
|
||||
while( (!p_vpar->p_fifo->b_die) && (!p_vpar->p_fifo->b_error) )
|
||||
{
|
||||
intf_ErrMsg("vpar error: can't spawn video parser thread");
|
||||
module_Unneed( p_vpar->p_idct_module );
|
||||
module_Unneed( p_vpar->p_motion_module );
|
||||
free( p_vpar );
|
||||
return( 0 );
|
||||
/* Find the next sequence header in the stream */
|
||||
p_vpar->p_fifo->b_error = vpar_NextSequenceHeader( p_vpar );
|
||||
|
||||
while( (!p_vpar->p_fifo->b_die) && (!p_vpar->p_fifo->b_error) )
|
||||
{
|
||||
p_vpar->c_loops++;
|
||||
|
||||
/* Parse the next sequence, group or picture header */
|
||||
if( vpar_ParseHeader( p_vpar ) )
|
||||
{
|
||||
/* End of sequence */
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
intf_DbgMsg("vpar debug: video parser thread (%p) created", p_vpar);
|
||||
return( p_vpar->thread_id );
|
||||
}
|
||||
/*
|
||||
* Error loop
|
||||
*/
|
||||
if( p_vpar->p_fifo->b_error )
|
||||
{
|
||||
mpeg_vdec_ErrorThread( p_vpar );
|
||||
}
|
||||
|
||||
/* following functions are local */
|
||||
/* End of thread */
|
||||
mpeg_vdec_EndThread( p_vpar );
|
||||
|
||||
if( p_vpar->p_fifo->b_error )
|
||||
{
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* InitThread: initialize vpar output thread
|
||||
* mpeg_vdec_Init: initialize vpar output thread
|
||||
*****************************************************************************
|
||||
* This function is called from RunThread and performs the second step of the
|
||||
* initialization. It returns 0 on success. Note that the thread's flag are not
|
||||
* modified inside this function.
|
||||
* This function is called from mpeg_vdec_Run and performs the second step
|
||||
* of the initialization. It returns 0 on success. Note that the thread's
|
||||
* flag are not modified inside this function.
|
||||
*****************************************************************************/
|
||||
static int InitThread( vpar_thread_t *p_vpar )
|
||||
static int mpeg_vdec_Init( vpar_thread_t *p_vpar )
|
||||
{
|
||||
intf_DbgMsg("vpar debug: initializing video parser thread %p", p_vpar);
|
||||
|
||||
/*
|
||||
* Choose the best motion compensation module
|
||||
*/
|
||||
@ -133,7 +208,7 @@ static int InitThread( vpar_thread_t *p_vpar )
|
||||
{
|
||||
intf_ErrMsg( "vpar error: no suitable motion compensation module" );
|
||||
free( p_vpar );
|
||||
return( 0 );
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
#define f ( p_vpar->p_motion_module->p_functions->motion.functions.motion )
|
||||
@ -150,7 +225,7 @@ static int InitThread( vpar_thread_t *p_vpar )
|
||||
intf_ErrMsg( "vpar error: no suitable IDCT module" );
|
||||
module_Unneed( p_vpar->p_motion_module );
|
||||
free( p_vpar );
|
||||
return( 0 );
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
#define f p_vpar->p_idct_module->p_functions->idct.functions.idct
|
||||
@ -163,8 +238,8 @@ static int InitThread( vpar_thread_t *p_vpar )
|
||||
#undef f
|
||||
|
||||
/* Initialize input bitstream */
|
||||
p_vpar->p_config->decoder_config.pf_init_bit_stream( &p_vpar->bit_stream,
|
||||
p_vpar->p_config->decoder_config.p_decoder_fifo, BitstreamCallback,
|
||||
p_vpar->p_config->pf_init_bit_stream( &p_vpar->bit_stream,
|
||||
p_vpar->p_config->p_decoder_fifo, BitstreamCallback,
|
||||
(void *)p_vpar );
|
||||
|
||||
/* Initialize parsing data */
|
||||
@ -205,67 +280,18 @@ static int InitThread( vpar_thread_t *p_vpar )
|
||||
vpar_InitPool( p_vpar );
|
||||
|
||||
/* Mark thread as running and return */
|
||||
intf_DbgMsg("vpar debug: InitThread(%p) succeeded", p_vpar);
|
||||
intf_DbgMsg("vpar debug: mpeg_vdec_Init(%p) succeeded", p_vpar);
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* RunThread: generic parser thread
|
||||
*****************************************************************************
|
||||
* Video parser thread. This function only returns when the thread is
|
||||
* terminated.
|
||||
*****************************************************************************/
|
||||
static void RunThread( vpar_thread_t *p_vpar )
|
||||
{
|
||||
intf_DbgMsg("vpar debug: running video parser thread (%p) (pid == %i)", p_vpar, getpid());
|
||||
|
||||
/*
|
||||
* Initialize thread
|
||||
*/
|
||||
p_vpar->p_fifo->b_error = InitThread( p_vpar );
|
||||
|
||||
/*
|
||||
* Main loop - it is not executed if an error occured during
|
||||
* initialization
|
||||
*/
|
||||
while( (!p_vpar->p_fifo->b_die) && (!p_vpar->p_fifo->b_error) )
|
||||
{
|
||||
/* Find the next sequence header in the stream */
|
||||
p_vpar->p_fifo->b_error = vpar_NextSequenceHeader( p_vpar );
|
||||
|
||||
while( (!p_vpar->p_fifo->b_die) && (!p_vpar->p_fifo->b_error) )
|
||||
{
|
||||
p_vpar->c_loops++;
|
||||
|
||||
/* Parse the next sequence, group or picture header */
|
||||
if( vpar_ParseHeader( p_vpar ) )
|
||||
{
|
||||
/* End of sequence */
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Error loop
|
||||
*/
|
||||
if( p_vpar->p_fifo->b_error )
|
||||
{
|
||||
ErrorThread( p_vpar );
|
||||
}
|
||||
|
||||
/* End of thread */
|
||||
EndThread( p_vpar );
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* ErrorThread: RunThread() error loop
|
||||
* mpeg_vdec_ErrorThread: 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( vpar_thread_t *p_vpar )
|
||||
static void mpeg_vdec_ErrorThread( vpar_thread_t *p_vpar )
|
||||
{
|
||||
/* We take the lock, because we are going to read/write the start/end
|
||||
* indexes of the decoder fifo */
|
||||
@ -291,12 +317,12 @@ static void ErrorThread( vpar_thread_t *p_vpar )
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* EndThread: thread destruction
|
||||
* mpeg_vdec_EndThread: thread destruction
|
||||
*****************************************************************************
|
||||
* This function is called when the thread ends after a sucessful
|
||||
* initialization.
|
||||
*****************************************************************************/
|
||||
static void EndThread( vpar_thread_t *p_vpar )
|
||||
static void mpeg_vdec_EndThread( vpar_thread_t *p_vpar )
|
||||
{
|
||||
intf_DbgMsg("vpar debug: destroying video parser thread %p", p_vpar);
|
||||
|
@ -2,7 +2,7 @@
|
||||
* video_parser.h : video parser thread
|
||||
*****************************************************************************
|
||||
* Copyright (C) 1999, 2000 VideoLAN
|
||||
* $Id: video_parser.h,v 1.16 2001/10/11 13:19:27 massiot Exp $
|
||||
* $Id: video_parser.h,v 1.1 2001/11/13 12:09:18 henri Exp $
|
||||
*
|
||||
* Authors: Christophe Massiot <massiot@via.ecp.fr>
|
||||
* Jean-Marc Dressler <polux@via.ecp.fr>
|
||||
@ -309,7 +309,7 @@ typedef struct vpar_thread_s
|
||||
|
||||
/* Input properties */
|
||||
decoder_fifo_t * p_fifo; /* PES input fifo */
|
||||
vdec_config_t * p_config;
|
||||
decoder_config_t * p_config;
|
||||
|
||||
/* Output properties */
|
||||
vout_thread_t * p_vout; /* video output thread */
|
@ -2,7 +2,7 @@
|
||||
* vpar_blocks.c : blocks parsing
|
||||
*****************************************************************************
|
||||
* Copyright (C) 1999, 2000 VideoLAN
|
||||
* $Id: vpar_blocks.c,v 1.14 2001/10/11 16:12:43 massiot Exp $
|
||||
* $Id: vpar_blocks.c,v 1.1 2001/11/13 12:09:18 henri Exp $
|
||||
*
|
||||
* Authors: Michel Lespinasse <walken@zoy.org>
|
||||
* Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
|
||||
@ -34,15 +34,16 @@
|
||||
#include "common.h"
|
||||
#include "threads.h"
|
||||
#include "mtime.h"
|
||||
|
||||
#include "intf_msg.h"
|
||||
|
||||
#include "stream_control.h"
|
||||
#include "input_ext-dec.h"
|
||||
|
||||
#include "video.h"
|
||||
#include "video_output.h"
|
||||
|
||||
#include "modules_export.h"
|
||||
#include "stream_control.h"
|
||||
#include "input_ext-dec.h"
|
||||
|
||||
|
||||
#include "vdec_ext-plugins.h"
|
||||
#include "vpar_pool.h"
|
||||
#include "video_parser.h"
|
@ -2,7 +2,7 @@
|
||||
* video_parser.h : Variable Length Codes
|
||||
*****************************************************************************
|
||||
* Copyright (C) 1999, 2000 VideoLAN
|
||||
* $Id: vpar_blocks.h,v 1.6 2001/08/22 17:21:46 massiot Exp $
|
||||
* $Id: vpar_blocks.h,v 1.1 2001/11/13 12:09:18 henri Exp $
|
||||
*
|
||||
* Authors: Christophe Massiot <massiot@via.ecp.fr>
|
||||
* Jean-Marc Dressler <polux@via.ecp.fr>
|
@ -2,7 +2,7 @@
|
||||
* vpar_headers.c : headers parsing
|
||||
*****************************************************************************
|
||||
* Copyright (C) 1999, 2000 VideoLAN
|
||||
* $Id: vpar_headers.c,v 1.12 2001/10/11 13:19:27 massiot Exp $
|
||||
* $Id: vpar_headers.c,v 1.1 2001/11/13 12:09:18 henri Exp $
|
||||
*
|
||||
* Authors: Christophe Massiot <massiot@via.ecp.fr>
|
||||
* Stéphane Borel <stef@via.ecp.fr>
|
||||
@ -34,15 +34,16 @@
|
||||
#include "common.h"
|
||||
#include "threads.h"
|
||||
#include "mtime.h"
|
||||
|
||||
#include "intf_msg.h"
|
||||
|
||||
#include "stream_control.h"
|
||||
#include "input_ext-dec.h"
|
||||
|
||||
#include "video.h"
|
||||
#include "video_output.h"
|
||||
|
||||
#include "modules_export.h"
|
||||
#include "stream_control.h"
|
||||
#include "input_ext-dec.h"
|
||||
|
||||
|
||||
#include "vdec_ext-plugins.h"
|
||||
#include "vpar_pool.h"
|
||||
#include "video_parser.h"
|
||||
@ -769,7 +770,7 @@ static void PictureHeader( vpar_thread_t * p_vpar )
|
||||
p_vpar->picture.b_current_field =
|
||||
(i_structure == BOTTOM_FIELD );
|
||||
|
||||
if( !p_vpar->p_config->decoder_config.p_stream_ctrl->b_grayscale )
|
||||
if( !p_vpar->p_config->p_stream_ctrl->b_grayscale )
|
||||
{
|
||||
switch( p_vpar->sequence.i_chroma_format )
|
||||
{
|
@ -2,7 +2,7 @@
|
||||
* vpar_pool.c : management of the pool of decoder threads
|
||||
*****************************************************************************
|
||||
* Copyright (C) 1999, 2000, 2001 VideoLAN
|
||||
* $Id: vpar_pool.c,v 1.4 2001/10/11 13:19:27 massiot Exp $
|
||||
* $Id: vpar_pool.c,v 1.1 2001/11/13 12:09:18 henri Exp $
|
||||
*
|
||||
* Authors: Christophe Massiot <massiot@via.ecp.fr>
|
||||
*
|
||||
@ -33,15 +33,16 @@
|
||||
#include "common.h"
|
||||
#include "threads.h"
|
||||
#include "mtime.h"
|
||||
|
||||
#include "intf_msg.h"
|
||||
|
||||
#include "stream_control.h"
|
||||
#include "input_ext-dec.h"
|
||||
|
||||
#include "video.h"
|
||||
#include "video_output.h"
|
||||
|
||||
#include "modules_export.h"
|
||||
#include "stream_control.h"
|
||||
#include "input_ext-dec.h"
|
||||
|
||||
|
||||
#include "vdec_ext-plugins.h"
|
||||
#include "vpar_pool.h"
|
||||
#include "video_parser.h"
|
||||
@ -113,7 +114,7 @@ void vpar_SpawnPool( vpar_thread_t * p_vpar )
|
||||
int i_new_smp;
|
||||
stream_ctrl_t * p_control;
|
||||
|
||||
p_control = p_vpar->p_config->decoder_config.p_stream_ctrl;
|
||||
p_control = p_vpar->p_config->p_stream_ctrl;
|
||||
vlc_mutex_lock( &p_control->control_lock );
|
||||
i_new_smp = p_control->i_smp;
|
||||
vlc_mutex_unlock( &p_control->control_lock );
|
@ -2,7 +2,7 @@
|
||||
* vpar_pool.h : video parser/video decoders communication
|
||||
*****************************************************************************
|
||||
* Copyright (C) 1999, 2000 VideoLAN
|
||||
* $Id: vpar_pool.h,v 1.4 2001/10/11 13:19:27 massiot Exp $
|
||||
* $Id: vpar_pool.h,v 1.1 2001/11/13 12:09:18 henri Exp $
|
||||
*
|
||||
* Authors: Christophe Massiot <massiot@via.ecp.fr>
|
||||
*
|
@ -2,7 +2,7 @@
|
||||
* vpar_synchro.c : frame dropping routines
|
||||
*****************************************************************************
|
||||
* Copyright (C) 1999, 2000 VideoLAN
|
||||
* $Id: vpar_synchro.c,v 1.5 2001/10/01 16:18:49 massiot Exp $
|
||||
* $Id: vpar_synchro.c,v 1.1 2001/11/13 12:09:18 henri Exp $
|
||||
*
|
||||
* Authors: Christophe Massiot <massiot@via.ecp.fr>
|
||||
* Samuel Hocevar <sam@via.ecp.fr>
|
||||
@ -102,20 +102,21 @@
|
||||
#include "common.h"
|
||||
#include "threads.h"
|
||||
#include "mtime.h"
|
||||
|
||||
#include "intf_msg.h"
|
||||
|
||||
#include "stream_control.h"
|
||||
#include "input_ext-dec.h"
|
||||
#include "main.h"
|
||||
|
||||
#include "video.h"
|
||||
#include "video_output.h"
|
||||
|
||||
#include "modules_export.h"
|
||||
#include "stream_control.h"
|
||||
#include "input_ext-dec.h"
|
||||
|
||||
#include "vdec_ext-plugins.h"
|
||||
#include "vpar_pool.h"
|
||||
#include "video_parser.h"
|
||||
|
||||
#include "main.h"
|
||||
|
||||
/*
|
||||
* Local prototypes
|
29
plugins/spu_dec/Makefile
Normal file
29
plugins/spu_dec/Makefile
Normal file
@ -0,0 +1,29 @@
|
||||
###############################################################################
|
||||
# vlc (VideoLAN Client) MPEG audio decoder module makefile
|
||||
# (c)2001 VideoLAN
|
||||
###############################################################################
|
||||
|
||||
#
|
||||
# Objects
|
||||
#
|
||||
PLUGIN_C = spu_decoder.o
|
||||
BUILTIN_C = $(PLUGIN_C:%.o=BUILTIN_%.o)
|
||||
|
||||
ALL_OBJ = $(PLUGIN_C) $(BUILTIN_C)
|
||||
#
|
||||
# Virtual targets
|
||||
#
|
||||
|
||||
include ../../Makefile.modules
|
||||
|
||||
#
|
||||
# Real targets
|
||||
#
|
||||
|
||||
../spu_dec.so: $(PLUGIN_C)
|
||||
$(CC) $(PCFLAGS) -o $@ $^ $(PLCFLAGS)
|
||||
|
||||
../spu_dec.a: $(BUILTIN_C)
|
||||
ar r $@ $^
|
||||
$(RANLIB) $@
|
||||
|
@ -2,7 +2,7 @@
|
||||
* spu_decoder.c : spu decoder thread
|
||||
*****************************************************************************
|
||||
* Copyright (C) 2000 VideoLAN
|
||||
* $Id: spu_decoder.c,v 1.49 2001/09/26 12:32:25 massiot Exp $
|
||||
* $Id: spu_decoder.c,v 1.1 2001/11/13 12:09:18 henri Exp $
|
||||
*
|
||||
* Authors: Samuel Hocevar <sam@zoy.org>
|
||||
*
|
||||
@ -21,6 +21,9 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
|
||||
*****************************************************************************/
|
||||
|
||||
#define MODULE_NAME spu_dec
|
||||
#include "modules_inner.h"
|
||||
|
||||
/*****************************************************************************
|
||||
* Preamble
|
||||
*****************************************************************************/
|
||||
@ -41,24 +44,26 @@
|
||||
#include "common.h"
|
||||
#include "threads.h"
|
||||
#include "mtime.h"
|
||||
|
||||
#include "intf_msg.h"
|
||||
|
||||
#include "stream_control.h"
|
||||
#include "input_ext-dec.h"
|
||||
|
||||
#include "video.h"
|
||||
#include "video_output.h"
|
||||
|
||||
#include "modules.h"
|
||||
#include "modules_export.h"
|
||||
#include "stream_control.h"
|
||||
#include "input_ext-dec.h"
|
||||
|
||||
#include "spu_decoder.h"
|
||||
|
||||
/*****************************************************************************
|
||||
* Local prototypes
|
||||
*****************************************************************************/
|
||||
static int InitThread ( spudec_thread_t * );
|
||||
static void RunThread ( spudec_thread_t * );
|
||||
static void ErrorThread ( spudec_thread_t * );
|
||||
static void EndThread ( spudec_thread_t * );
|
||||
static int spu_dec_Probe ( probedata_t * );
|
||||
static int spu_dec_Run ( decoder_config_t * );
|
||||
static int spu_dec_Init ( spudec_thread_t * );
|
||||
static void spu_dec_ErrorThread ( spudec_thread_t * );
|
||||
static void spu_dec_EndThread ( spudec_thread_t * );
|
||||
|
||||
static int SyncPacket ( spudec_thread_t * );
|
||||
static void ParsePacket ( spudec_thread_t * );
|
||||
@ -66,11 +71,56 @@ static int ParseControlSequences( spudec_thread_t *, subpicture_t * );
|
||||
static int ParseRLE ( spudec_thread_t *, subpicture_t *, u8 * );
|
||||
|
||||
/*****************************************************************************
|
||||
* spudec_CreateThread: create a spu decoder thread
|
||||
* Capabilities
|
||||
*****************************************************************************/
|
||||
vlc_thread_t spudec_CreateThread( vdec_config_t * p_config )
|
||||
void _M( spu_dec_getfunctions )( function_list_t * p_function_list )
|
||||
{
|
||||
p_function_list->pf_probe = spu_dec_Probe;
|
||||
p_function_list->functions.dec.pf_RunThread = spu_dec_Run;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* Build configuration tree.
|
||||
*****************************************************************************/
|
||||
MODULE_CONFIG_START
|
||||
ADD_WINDOW( "Configuration for SPU decoder module" )
|
||||
ADD_COMMENT( "Nothing to configure" )
|
||||
MODULE_CONFIG_STOP
|
||||
|
||||
MODULE_INIT_START
|
||||
p_module->i_capabilities = MODULE_CAPABILITY_DEC;
|
||||
p_module->psz_longname = "Subtitles decoder module";
|
||||
MODULE_INIT_STOP
|
||||
|
||||
MODULE_ACTIVATE_START
|
||||
_M( spu_dec_getfunctions )( &p_module->p_functions->dec );
|
||||
MODULE_ACTIVATE_STOP
|
||||
|
||||
MODULE_DEACTIVATE_START
|
||||
MODULE_DEACTIVATE_STOP
|
||||
|
||||
/*****************************************************************************
|
||||
* spu_dec_Probe: probe the decoder and return score
|
||||
*****************************************************************************
|
||||
* Tries to launch a decoder and return score so that the interface is able
|
||||
* to chose.
|
||||
*****************************************************************************/
|
||||
static int spu_dec_Probe( probedata_t *p_data )
|
||||
{
|
||||
if( p_data->i_type == DVD_SPU_ES )
|
||||
return( 50 );
|
||||
else
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* spu_dec_Run: this function is called just after the thread is created
|
||||
*****************************************************************************/
|
||||
static int spu_dec_Run( decoder_config_t * p_config )
|
||||
{
|
||||
spudec_thread_t * p_spudec;
|
||||
|
||||
intf_WarnMsg( 3, "spudec: thread launched. Initializing ..." );
|
||||
|
||||
/* Allocate the memory needed to store the thread's structure */
|
||||
p_spudec = (spudec_thread_t *)malloc( sizeof(spudec_thread_t) );
|
||||
@ -79,91 +129,20 @@ vlc_thread_t spudec_CreateThread( vdec_config_t * p_config )
|
||||
{
|
||||
intf_ErrMsg( "spudec error: not enough memory "
|
||||
"for spudec_CreateThread() to create the new thread" );
|
||||
return( 0 );
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Initialize the thread properties
|
||||
*/
|
||||
p_spudec->p_config = p_config;
|
||||
|
||||
p_spudec->p_fifo = p_config->decoder_config.p_decoder_fifo;
|
||||
|
||||
/* Spawn a video output if there is none */
|
||||
vlc_mutex_lock( &p_vout_bank->lock );
|
||||
|
||||
if( p_vout_bank->i_count == 0 )
|
||||
{
|
||||
intf_WarnMsg( 1, "spudec: no vout present, spawning one" );
|
||||
|
||||
p_spudec->p_vout = vout_CreateThread( NULL, 0, 0 );
|
||||
|
||||
/* Everything failed */
|
||||
if( p_spudec->p_vout == NULL )
|
||||
{
|
||||
intf_Msg( "spudec: can't open vout, aborting" );
|
||||
vlc_mutex_unlock( &p_vout_bank->lock );
|
||||
free( p_spudec );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
p_vout_bank->pp_vout[ p_vout_bank->i_count ] = p_spudec->p_vout;
|
||||
p_vout_bank->i_count++;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Take the first video output FIXME: take the best one */
|
||||
p_spudec->p_vout = p_vout_bank->pp_vout[ 0 ];
|
||||
}
|
||||
|
||||
vlc_mutex_unlock( &p_vout_bank->lock );
|
||||
|
||||
/* Spawn the spu decoder thread */
|
||||
if ( vlc_thread_create(&p_spudec->thread_id, "spu decoder",
|
||||
(vlc_thread_func_t)RunThread, (void *)p_spudec) )
|
||||
{
|
||||
intf_ErrMsg( "spudec error: can't spawn spu decoder thread" );
|
||||
free( p_spudec );
|
||||
return 0;
|
||||
}
|
||||
|
||||
return( p_spudec->thread_id );
|
||||
}
|
||||
|
||||
/* following functions are local */
|
||||
|
||||
/*****************************************************************************
|
||||
* InitThread: initialize spu decoder thread
|
||||
*****************************************************************************
|
||||
* This function is called from RunThread and performs the second step of the
|
||||
* initialization. It returns 0 on success. Note that the thread's flag are not
|
||||
* modified inside this function.
|
||||
*****************************************************************************/
|
||||
static int InitThread( spudec_thread_t *p_spudec )
|
||||
{
|
||||
p_spudec->p_config->decoder_config.pf_init_bit_stream(
|
||||
&p_spudec->bit_stream,
|
||||
p_spudec->p_config->decoder_config.p_decoder_fifo, NULL, NULL );
|
||||
|
||||
/* Mark thread as running and return */
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* RunThread: spu decoder thread
|
||||
*****************************************************************************
|
||||
* spu decoder thread. This function only returns when the thread is
|
||||
* terminated.
|
||||
*****************************************************************************/
|
||||
static void RunThread( spudec_thread_t *p_spudec )
|
||||
{
|
||||
intf_WarnMsg( 3, "spudec: spu decoder thread %i spawned", getpid() );
|
||||
|
||||
p_spudec->p_fifo = p_config->p_decoder_fifo;
|
||||
|
||||
/*
|
||||
* Initialize thread and free configuration
|
||||
*/
|
||||
p_spudec->p_fifo->b_error = InitThread( p_spudec );
|
||||
p_spudec->p_fifo->b_error = spu_dec_Init( p_spudec );
|
||||
|
||||
/*
|
||||
* Main loop - it is not executed if an error occured during
|
||||
@ -182,22 +161,77 @@ static void RunThread( spudec_thread_t *p_spudec )
|
||||
*/
|
||||
if( p_spudec->p_fifo->b_error )
|
||||
{
|
||||
ErrorThread( p_spudec );
|
||||
spu_dec_ErrorThread( p_spudec );
|
||||
}
|
||||
|
||||
/* End of thread */
|
||||
intf_WarnMsg( 3, "spudec: destroying spu decoder thread %i", getpid() );
|
||||
EndThread( p_spudec );
|
||||
spu_dec_EndThread( p_spudec );
|
||||
|
||||
if( p_spudec->p_fifo->b_error )
|
||||
{
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
|
||||
}
|
||||
|
||||
/* following functions are local */
|
||||
|
||||
/*****************************************************************************
|
||||
* spu_dec_Init: initialize spu decoder thread
|
||||
*****************************************************************************
|
||||
* This function is called from RunThread and performs the second step of the
|
||||
* initialization. It returns 0 on success. Note that the thread's flag are not
|
||||
* modified inside this function.
|
||||
*****************************************************************************/
|
||||
static int spu_dec_Init( spudec_thread_t *p_spudec )
|
||||
{
|
||||
/* Spawn a video output if there is none */
|
||||
vlc_mutex_lock( &p_vout_bank->lock );
|
||||
|
||||
if( p_vout_bank->i_count == 0 )
|
||||
{
|
||||
intf_WarnMsg( 1, "spudec: no vout present, spawning one" );
|
||||
|
||||
p_spudec->p_vout = vout_CreateThread( NULL, 0, 0 );
|
||||
|
||||
/* Everything failed */
|
||||
if( p_spudec->p_vout == NULL )
|
||||
{
|
||||
intf_Msg( "spudec: can't open vout, aborting" );
|
||||
vlc_mutex_unlock( &p_vout_bank->lock );
|
||||
free( p_spudec );
|
||||
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
p_vout_bank->pp_vout[ p_vout_bank->i_count ] = p_spudec->p_vout;
|
||||
p_vout_bank->i_count++;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Take the first video output FIXME: take the best one */
|
||||
p_spudec->p_vout = p_vout_bank->pp_vout[ 0 ];
|
||||
}
|
||||
|
||||
vlc_mutex_unlock( &p_vout_bank->lock );
|
||||
p_spudec->p_config->pf_init_bit_stream(
|
||||
&p_spudec->bit_stream,
|
||||
p_spudec->p_config->p_decoder_fifo, NULL, NULL );
|
||||
|
||||
/* Mark thread as running and return */
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* ErrorThread: RunThread() error loop
|
||||
* spu_dec_ErrorThread: spu_dec_Run() 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( spudec_thread_t *p_spudec )
|
||||
static void spu_dec_ErrorThread( spudec_thread_t *p_spudec )
|
||||
{
|
||||
/* We take the lock, because we are going to read/write the start/end
|
||||
* indexes of the decoder fifo */
|
||||
@ -224,12 +258,12 @@ static void ErrorThread( spudec_thread_t *p_spudec )
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* EndThread: thread destruction
|
||||
* spu_dec_EndThread: thread destruction
|
||||
*****************************************************************************
|
||||
* This function is called when the thread ends after a sucessful
|
||||
* initialization.
|
||||
*****************************************************************************/
|
||||
static void EndThread( spudec_thread_t *p_spudec )
|
||||
static void spu_dec_EndThread( spudec_thread_t *p_spudec )
|
||||
{
|
||||
free( p_spudec->p_config );
|
||||
free( p_spudec );
|
@ -2,7 +2,7 @@
|
||||
* spu_decoder.h : sub picture unit decoder thread interface
|
||||
*****************************************************************************
|
||||
* Copyright (C) 1999, 2000 VideoLAN
|
||||
* $Id: spu_decoder.h,v 1.10 2001/05/11 15:10:01 sam Exp $
|
||||
* $Id: spu_decoder.h,v 1.1 2001/11/13 12:09:18 henri Exp $
|
||||
*
|
||||
* Authors: Samuel Hocevar <sam@zoy.org>
|
||||
*
|
||||
@ -37,7 +37,7 @@ typedef struct spudec_thread_s
|
||||
decoder_fifo_t * p_fifo; /* stores the PES stream data */
|
||||
/* The bit stream structure handles the PES stream at the bit level */
|
||||
bit_stream_t bit_stream;
|
||||
vdec_config_t * p_config;
|
||||
decoder_config_t * p_config;
|
||||
|
||||
/*
|
||||
* Output properties
|
||||
@ -91,5 +91,5 @@ static __inline__ unsigned int AddNibble( unsigned int i_code,
|
||||
/*****************************************************************************
|
||||
* Prototypes
|
||||
*****************************************************************************/
|
||||
vlc_thread_t spudec_CreateThread( vdec_config_t * p_config );
|
||||
vlc_thread_t spudec_CreateThread( decoder_config_t * p_config );
|
||||
|
@ -2,7 +2,7 @@
|
||||
* input_dec.c: Functions for the management of decoders
|
||||
*****************************************************************************
|
||||
* Copyright (C) 1999, 2000 VideoLAN
|
||||
* $Id: input_dec.c,v 1.13 2001/07/18 14:21:00 massiot Exp $
|
||||
* $Id: input_dec.c,v 1.14 2001/11/13 12:09:18 henri Exp $
|
||||
*
|
||||
* Authors: Christophe Massiot <massiot@via.ecp.fr>
|
||||
*
|
||||
@ -41,15 +41,45 @@
|
||||
#include "input_ext-intf.h"
|
||||
#include "input_ext-plugins.h"
|
||||
|
||||
#include "modules.h"
|
||||
|
||||
/*****************************************************************************
|
||||
* input_RunDecoder: spawns a new decoder thread
|
||||
*****************************************************************************/
|
||||
vlc_thread_t input_RunDecoder( decoder_capabilities_t * p_decoder,
|
||||
void * p_data )
|
||||
vlc_thread_t input_RunDecoder( void * p_data )
|
||||
{
|
||||
return( p_decoder->pf_create_thread( p_data ) );
|
||||
decoder_config_t * p_config;
|
||||
probedata_t probedata;
|
||||
|
||||
p_config = (decoder_config_t *)p_data;
|
||||
|
||||
probedata.i_type = p_config->i_type;
|
||||
p_config->p_dec_module = module_Need(
|
||||
MODULE_CAPABILITY_DEC, &probedata);
|
||||
if( p_config->p_dec_module == NULL )
|
||||
{
|
||||
intf_ErrMsg( "dec error: no suitable dec module for type 0x%x",
|
||||
p_config->i_type );
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/* Spawn the decoder thread */
|
||||
if ( vlc_thread_create(&p_config->thread_id,
|
||||
"decoder", (vlc_thread_func_t)p_config->p_dec_module->
|
||||
p_functions->dec.functions.dec.pf_RunThread, (void *)p_config) )
|
||||
{
|
||||
intf_ErrMsg( "dec error: can't spawn decoder thread \"%s\"",
|
||||
p_config->p_dec_module->psz_name );
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
intf_DbgMsg( "dec debug: decoder \"%s\"thread (%p) created",
|
||||
p_config->p_dec_module->psz_name, p_dec );
|
||||
|
||||
return p_config->thread_id;
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* input_EndDecoder: kills a decoder thread and waits until it's finished
|
||||
*****************************************************************************/
|
||||
@ -78,6 +108,9 @@ void input_EndDecoder( input_thread_t * p_input, es_descriptor_t * p_es )
|
||||
vlc_thread_join( p_es->thread_id );
|
||||
// vlc_mutex_lock( &p_input->stream.stream_lock );
|
||||
|
||||
/* Unneed module*/
|
||||
module_Unneed( p_es->p_dec_config->p_dec_module );
|
||||
|
||||
/* Freeing all packets still in the decoder fifo. */
|
||||
while( !DECODER_FIFO_ISEMPTY( *p_es->p_decoder_fifo ) )
|
||||
{
|
||||
|
@ -2,7 +2,7 @@
|
||||
* input_programs.c: es_descriptor_t, pgrm_descriptor_t management
|
||||
*****************************************************************************
|
||||
* Copyright (C) 1999, 2000 VideoLAN
|
||||
* $Id: input_programs.c,v 1.63 2001/10/03 15:10:55 sam Exp $
|
||||
* $Id: input_programs.c,v 1.64 2001/11/13 12:09:18 henri Exp $
|
||||
*
|
||||
* Authors: Christophe Massiot <massiot@via.ecp.fr>
|
||||
*
|
||||
@ -553,44 +553,20 @@ static int InitDecConfig( input_thread_t * p_input, es_descriptor_t * p_es,
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* GetVdecConfig: returns a valid vdec_config_t
|
||||
* GetDecConfig: returns a valid decoder_config_t
|
||||
*****************************************************************************/
|
||||
static vdec_config_t * GetVdecConfig( input_thread_t * p_input,
|
||||
static decoder_config_t * GetDecConfig( input_thread_t * p_input,
|
||||
es_descriptor_t * p_es )
|
||||
{
|
||||
vdec_config_t * p_config;
|
||||
decoder_config_t * p_config;
|
||||
|
||||
p_config = (vdec_config_t *)malloc( sizeof(vdec_config_t) );
|
||||
p_config = (decoder_config_t *)malloc( sizeof(decoder_config_t) );
|
||||
if( p_config == NULL )
|
||||
{
|
||||
intf_ErrMsg( "Unable to allocate memory in GetVdecConfig" );
|
||||
intf_ErrMsg( "Unable to allocate memory in GetDecConfig" );
|
||||
return( NULL );
|
||||
}
|
||||
if( InitDecConfig( p_input, p_es, &p_config->decoder_config ) == -1 )
|
||||
{
|
||||
free( p_config );
|
||||
return( NULL );
|
||||
}
|
||||
|
||||
return( p_config );
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* GetAdecConfig: returns a valid adec_config_t
|
||||
*****************************************************************************/
|
||||
static adec_config_t * GetAdecConfig( input_thread_t * p_input,
|
||||
es_descriptor_t * p_es )
|
||||
{
|
||||
adec_config_t * p_config;
|
||||
|
||||
p_config = (adec_config_t *)malloc( sizeof(adec_config_t));
|
||||
if( p_config == NULL )
|
||||
{
|
||||
intf_ErrMsg( "Unable to allocate memory in GetAdecConfig" );
|
||||
return( NULL );
|
||||
}
|
||||
|
||||
if( InitDecConfig( p_input, p_es, &p_config->decoder_config ) == -1 )
|
||||
if( InitDecConfig( p_input, p_es, p_config ) == -1 )
|
||||
{
|
||||
free( p_config );
|
||||
return( NULL );
|
||||
@ -617,7 +593,6 @@ vlc_thread_t lpcmdec_CreateThread( void * );
|
||||
int input_SelectES( input_thread_t * p_input, es_descriptor_t * p_es )
|
||||
{
|
||||
/* FIXME ! */
|
||||
decoder_capabilities_t decoder;
|
||||
void * p_config;
|
||||
|
||||
if( p_es == NULL )
|
||||
@ -638,83 +613,47 @@ int input_SelectES( input_thread_t * p_input, es_descriptor_t * p_es )
|
||||
|
||||
switch( p_es->i_type )
|
||||
{
|
||||
case AC3_AUDIO_ES:
|
||||
case MPEG1_AUDIO_ES:
|
||||
case MPEG2_AUDIO_ES:
|
||||
case LPCM_AUDIO_ES:
|
||||
if( p_main->b_audio )
|
||||
{
|
||||
decoder.pf_create_thread = adec_CreateThread;
|
||||
p_config = (void *)GetAdecConfig( p_input, p_es );
|
||||
p_main->b_ac3 = 0;
|
||||
decoder_config_t * p_dec_config;
|
||||
|
||||
p_dec_config = GetDecConfig( p_input, p_es );
|
||||
p_config =(void *)p_dec_config;
|
||||
p_dec_config->i_type = p_es->i_type;
|
||||
|
||||
p_main->b_ac3 = ( p_es->i_type == AC3_AUDIO_ES );
|
||||
/* Useful to Unned decoder module */
|
||||
p_es->p_dec_config = p_dec_config;
|
||||
|
||||
/* Release the lock, not to block the input thread during
|
||||
* the creation of the thread. */
|
||||
vlc_mutex_unlock( &p_input->stream.stream_lock );
|
||||
p_es->thread_id = input_RunDecoder( &decoder, p_config );
|
||||
p_es->thread_id = input_RunDecoder( p_config );
|
||||
vlc_mutex_lock( &p_input->stream.stream_lock );
|
||||
}
|
||||
break;
|
||||
|
||||
case MPEG1_VIDEO_ES:
|
||||
case MPEG2_VIDEO_ES:
|
||||
if( p_main->b_video )
|
||||
{
|
||||
decoder.pf_create_thread = vpar_CreateThread;
|
||||
p_config = (void *)GetVdecConfig( p_input, p_es );
|
||||
|
||||
/* Release the lock, not to block the input thread during
|
||||
* the creation of the thread. */
|
||||
vlc_mutex_unlock( &p_input->stream.stream_lock );
|
||||
p_es->thread_id = input_RunDecoder( &decoder, p_config );
|
||||
vlc_mutex_lock( &p_input->stream.stream_lock );
|
||||
}
|
||||
break;
|
||||
|
||||
case AC3_AUDIO_ES:
|
||||
if( p_main->b_audio )
|
||||
{
|
||||
if( main_GetIntVariable( AOUT_SPDIF_VAR, 0 ) )
|
||||
{
|
||||
decoder.pf_create_thread = spdif_CreateThread;
|
||||
}
|
||||
else
|
||||
{
|
||||
decoder.pf_create_thread = ac3dec_CreateThread;
|
||||
}
|
||||
|
||||
p_config = (void *)GetAdecConfig( p_input, p_es );
|
||||
p_main->b_ac3 = 1;
|
||||
|
||||
/* Release the lock, not to block the input thread during
|
||||
* the creation of the thread. */
|
||||
vlc_mutex_unlock( &p_input->stream.stream_lock );
|
||||
p_es->thread_id = input_RunDecoder( &decoder, p_config );
|
||||
vlc_mutex_lock( &p_input->stream.stream_lock );
|
||||
}
|
||||
break;
|
||||
case LPCM_AUDIO_ES:
|
||||
if( p_main->b_audio )
|
||||
{
|
||||
decoder.pf_create_thread = lpcmdec_CreateThread;
|
||||
p_config = (void *)GetAdecConfig( p_input, p_es );
|
||||
p_main->b_ac3 = 0;
|
||||
|
||||
/* Release the lock, not to block the input thread during
|
||||
* the creation of the thread. */
|
||||
vlc_mutex_unlock( &p_input->stream.stream_lock );
|
||||
p_es->thread_id = input_RunDecoder( &decoder, p_config );
|
||||
vlc_mutex_lock( &p_input->stream.stream_lock );
|
||||
}
|
||||
break;
|
||||
case DVD_SPU_ES:
|
||||
if( p_main->b_video )
|
||||
{
|
||||
decoder.pf_create_thread = spudec_CreateThread;
|
||||
p_config = (void *)GetVdecConfig( p_input, p_es );
|
||||
decoder_config_t * p_dec_config;
|
||||
|
||||
p_dec_config = GetDecConfig( p_input, p_es );
|
||||
p_config = (void *)p_dec_config;
|
||||
p_dec_config->i_type = p_es->i_type;
|
||||
/* Useful to Unned decoder module */
|
||||
p_es->p_dec_config = p_dec_config;
|
||||
|
||||
/* Release the lock, not to block the input thread during
|
||||
* the creation of the thread. */
|
||||
vlc_mutex_unlock( &p_input->stream.stream_lock );
|
||||
p_es->thread_id = input_RunDecoder( &decoder, p_config );
|
||||
p_es->thread_id = input_RunDecoder( p_config );
|
||||
vlc_mutex_lock( &p_input->stream.stream_lock );
|
||||
}
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user