From 49a0736e1c0224ace17fd8598de948439dd0ed03 Mon Sep 17 00:00:00 2001 From: Henri Fallon Date: Tue, 13 Nov 2001 12:09:18 +0000 Subject: [PATCH] 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 --- AUTHORS | 4 +- Makefile | 32 +- TODO | 2 +- configure | 4 +- configure.in | 4 +- doc/developer/decoders.xml | 25 +- doc/developer/manual.xml | 11 +- include/common.h | 11 +- include/input_ext-dec.h | 65 +--- include/input_ext-intf.h | 14 +- include/input_ext-plugins.h | 4 +- include/modules.h | 31 +- include/modules_export.h | 75 +++- plugins/ac3_adec/Makefile | 29 ++ .../ac3_adec/ac3_adec.c | 355 +++++++++--------- .../ac3_adec/ac3_adec.h | 8 +- .../ac3_adec}/ac3_bit_allocate.c | 2 +- .../ac3_adec}/ac3_decoder.c | 10 +- .../ac3_adec}/ac3_decoder.h | 2 +- .../ac3_adec}/ac3_exponent.c | 8 +- .../ac3_adec}/ac3_exponent.h | 2 +- .../ac3_adec}/ac3_imdct.c | 2 +- .../ac3_adec}/ac3_internal.h | 2 +- .../ac3_adec}/ac3_mantissa.c | 8 +- .../ac3_adec}/ac3_mantissa.h | 2 +- .../ac3_adec}/ac3_parse.c | 10 +- .../ac3_adec}/ac3_rematrix.c | 2 +- plugins/ac3_spdif/Makefile | 29 ++ {src => plugins}/ac3_spdif/ac3_iec958.c | 8 +- {src => plugins}/ac3_spdif/ac3_iec958.h | 2 +- {src => plugins}/ac3_spdif/ac3_spdif.c | 295 ++++++++------- {src => plugins}/ac3_spdif/ac3_spdif.h | 9 +- plugins/lpcm_adec/Makefile | 29 ++ .../lpcm_adec/lpcm_adec.c | 243 ++++++------ .../lpcm_adec/lpcm_adec.h | 7 +- plugins/mpeg_adec/Makefile | 29 ++ .../mpeg_adec}/adec_layer1.c | 8 +- .../mpeg_adec}/adec_layer1.h | 2 +- .../mpeg_adec}/adec_layer2.c | 7 +- .../mpeg_adec}/adec_layer2.h | 2 +- .../mpeg_adec}/adec_math.c | 4 +- .../mpeg_adec}/adec_math.h | 2 +- .../mpeg_adec}/adec_test.c | 6 +- .../mpeg_adec/mpeg_adec.c | 273 +++++++------- .../mpeg_adec/mpeg_adec.h | 23 +- .../mpeg_adec/mpeg_adec_generic.c | 12 +- .../mpeg_adec/mpeg_adec_generic.h | 3 +- plugins/mpeg_vdec/Makefile | 29 ++ .../mpeg_vdec}/video_decoder.c | 10 +- .../mpeg_vdec}/video_decoder.h | 2 +- .../mpeg_vdec}/video_parser.c | 214 ++++++----- .../mpeg_vdec}/video_parser.h | 4 +- .../mpeg_vdec}/vpar_blocks.c | 9 +- .../mpeg_vdec}/vpar_blocks.h | 2 +- .../mpeg_vdec}/vpar_headers.c | 11 +- .../mpeg_vdec}/vpar_pool.c | 11 +- .../mpeg_vdec}/vpar_pool.h | 2 +- .../mpeg_vdec}/vpar_synchro.c | 11 +- plugins/spu_dec/Makefile | 29 ++ .../spu_dec}/spu_decoder.c | 204 +++++----- .../spu_dec}/spu_decoder.h | 6 +- src/input/input_dec.c | 41 +- src/input/input_programs.c | 115 ++---- 63 files changed, 1387 insertions(+), 1030 deletions(-) create mode 100644 plugins/ac3_adec/Makefile rename src/ac3_decoder/ac3_decoder_thread.c => plugins/ac3_adec/ac3_adec.c (77%) rename src/ac3_decoder/ac3_decoder_thread.h => plugins/ac3_adec/ac3_adec.h (89%) rename {src/ac3_decoder => plugins/ac3_adec}/ac3_bit_allocate.c (99%) rename {src/ac3_decoder => plugins/ac3_adec}/ac3_decoder.c (96%) rename {src/ac3_decoder => plugins/ac3_adec}/ac3_decoder.h (99%) rename {src/ac3_decoder => plugins/ac3_adec}/ac3_exponent.c (97%) rename {src/ac3_decoder => plugins/ac3_adec}/ac3_exponent.h (98%) rename {src/ac3_decoder => plugins/ac3_adec}/ac3_imdct.c (99%) rename {src/ac3_decoder => plugins/ac3_adec}/ac3_internal.h (96%) rename {src/ac3_decoder => plugins/ac3_adec}/ac3_mantissa.c (97%) rename {src/ac3_decoder => plugins/ac3_adec}/ac3_mantissa.h (99%) rename {src/ac3_decoder => plugins/ac3_adec}/ac3_parse.c (99%) rename {src/ac3_decoder => plugins/ac3_adec}/ac3_rematrix.c (97%) create mode 100644 plugins/ac3_spdif/Makefile rename {src => plugins}/ac3_spdif/ac3_iec958.c (98%) rename {src => plugins}/ac3_spdif/ac3_iec958.h (97%) rename {src => plugins}/ac3_spdif/ac3_spdif.c (76%) rename {src => plugins}/ac3_spdif/ac3_spdif.h (87%) create mode 100644 plugins/lpcm_adec/Makefile rename src/lpcm_decoder/lpcm_decoder_thread.c => plugins/lpcm_adec/lpcm_adec.c (54%) rename src/lpcm_decoder/lpcm_decoder_thread.h => plugins/lpcm_adec/lpcm_adec.h (92%) create mode 100644 plugins/mpeg_adec/Makefile rename {src/audio_decoder => plugins/mpeg_adec}/adec_layer1.c (98%) rename {src/audio_decoder => plugins/mpeg_adec}/adec_layer1.h (95%) rename {src/audio_decoder => plugins/mpeg_adec}/adec_layer2.c (99%) rename {src/audio_decoder => plugins/mpeg_adec}/adec_layer2.h (95%) rename {src/audio_decoder => plugins/mpeg_adec}/adec_math.c (99%) rename {src/audio_decoder => plugins/mpeg_adec}/adec_math.h (95%) rename {src/audio_decoder => plugins/mpeg_adec}/adec_test.c (96%) rename src/audio_decoder/audio_decoder.c => plugins/mpeg_adec/mpeg_adec.c (54%) rename src/audio_decoder/audio_decoder.h => plugins/mpeg_adec/mpeg_adec.h (77%) rename src/audio_decoder/adec_generic.c => plugins/mpeg_adec/mpeg_adec_generic.c (96%) rename src/audio_decoder/adec_generic.h => plugins/mpeg_adec/mpeg_adec_generic.h (95%) create mode 100644 plugins/mpeg_vdec/Makefile rename {src/video_decoder => plugins/mpeg_vdec}/video_decoder.c (99%) rename {src/video_decoder => plugins/mpeg_vdec}/video_decoder.h (96%) rename {src/video_decoder => plugins/mpeg_vdec}/video_parser.c (81%) rename {src/video_decoder => plugins/mpeg_vdec}/video_parser.h (99%) rename {src/video_decoder => plugins/mpeg_vdec}/vpar_blocks.c (99%) rename {src/video_decoder => plugins/mpeg_vdec}/vpar_blocks.h (99%) rename {src/video_decoder => plugins/mpeg_vdec}/vpar_headers.c (99%) rename {src/video_decoder => plugins/mpeg_vdec}/vpar_pool.c (98%) rename {src/video_decoder => plugins/mpeg_vdec}/vpar_pool.h (98%) rename {src/video_decoder => plugins/mpeg_vdec}/vpar_synchro.c (99%) create mode 100644 plugins/spu_dec/Makefile rename {src/spu_decoder => plugins/spu_dec}/spu_decoder.c (89%) rename {src/spu_decoder => plugins/spu_dec}/spu_decoder.h (95%) diff --git a/AUTHORS b/AUTHORS index 9d9f6ceb46..735ec0d673 100644 --- a/AUTHORS +++ b/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 diff --git a/Makefile b/Makefile index c35b73b87e..fce0309ef8 100644 --- a/Makefile +++ b/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) # diff --git a/TODO b/TODO index 91d648f9c7..8901ac88f2 100644 --- a/TODO +++ b/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 diff --git a/configure b/configure index 403e7aa669..fe91332a2d 100755 --- a/configure +++ b/configure @@ -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" diff --git a/configure.in b/configure.in index 172b75bd6e..407181d18c 100644 --- a/configure.in +++ b/configure.in @@ -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 diff --git a/doc/developer/decoders.xml b/doc/developer/decoders.xml index 354de019eb..6eea00bdbb 100644 --- a/doc/developer/decoders.xml +++ b/doc/developer/decoders.xml @@ -23,20 +23,20 @@ chapters. Decoder configuration -The input thread spawns the appropriate decoders [the relation is -currently hard-wired in src/input/input_programs.c]. -It then launches *_CreateThread(), with either -an adec_config_t (audio) or an vdec_config_t -(video) structure, described in include/input_ext-dec.h. +The input thread spawns the appropriate decoder modules from +src/input/input_dec.c. The Dec_CreateThread +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 module.pf_RunThread(), +with an decoder_config_t (audio) or an vdec_config_t +, described in include/input_ext-dec.h. -It contains some parameters relative to the output thread, which will -be described in the following chapters, and a generic -decoder_config_t, which gives the decoder the ES ID and type, and -pointers to a stream_control_t structure (gives -information on the play status), a decoder_fifo_t -and pf_init_bit_stream, which will be +The generic decoder_config_t structure, gives the decoder +the ES ID and type, and pointers to a stream_control_t +structure (gives information on the play status), a decoder_fifo_t + and pf_init_bit_stream, which will be described in the next two sections. @@ -379,7 +379,8 @@ seven methods : vdec_IDCT - ( vdec_thread_t * p_vdec, dctelem_t * p_block, int ) : + ( decoder_config_t * p_config, dctelem_t * p_block, int ) + : Does the complete 2-D IDCT. 64 coefficients are in p_block. diff --git a/doc/developer/manual.xml b/doc/developer/manual.xml index fb72b84b97..d27a67b6be 100644 --- a/doc/developer/manual.xml +++ b/doc/developer/manual.xml @@ -49,8 +49,15 @@ S.A.S. - - $Id: manual.xml,v 1.1 2001/07/16 15:54:59 massiot Exp $ + + Henri Fallon + + + Developer + VideoLAN project + + + $Id: manual.xml,v 1.2 2001/11/13 12:09:17 henri Exp $ 2001 Christophe Massiot, for IDEALX S.A.S. diff --git a/include/common.h b/include/common.h index 76193be5f3..91d2600941 100644 --- a/include/common.h +++ b/include/common.h @@ -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 * Vincent Seguin @@ -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 diff --git a/include/input_ext-dec.h b/include/input_ext-dec.h index 8504e2988a..bea98bc345 100644 --- a/include/input_ext-dec.h +++ b/include/input_ext-dec.h @@ -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 * Michel Kaempf @@ -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,53 +530,13 @@ typedef struct decoder_config_s void (* pf_bitstream_callback)( struct bit_stream_s *, boolean_t ), void * ); -} decoder_config_t; - -/***************************************************************************** - * vdec_config_t - ***************************************************************************** - * Pointers given to video decoders threads. - *****************************************************************************/ -struct vout_thread_s; + /* Decoder thread */ + vlc_thread_t thread_id; -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; + /* Plugin/Builtin properties */ + struct module_s * p_dec_module; +} decoder_config_t; /* * Communication interface between decoders and input diff --git a/include/input_ext-intf.h b/include/input_ext-intf.h index d9ea12dce3..8558005e46 100644 --- a/include/input_ext-intf.h +++ b/include/input_ext-intf.h @@ -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 * @@ -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 diff --git a/include/input_ext-plugins.h b/include/input_ext-plugins.h index ff806fdcb1..d2b73f2db4 100644 --- a/include/input_ext-plugins.h +++ b/include/input_ext-plugins.h @@ -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 * @@ -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 *, diff --git a/include/modules.h b/include/modules.h index 9acf2e2491..1dc79dadf0 100644 --- a/include/modules.h +++ b/include/modules.h @@ -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 * @@ -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; diff --git a/include/modules_export.h b/include/modules_export.h index e4b4951d45..15e312efca 100644 --- a/include/modules_export.h +++ b/include/modules_export.h @@ -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 diff --git a/plugins/ac3_adec/Makefile b/plugins/ac3_adec/Makefile new file mode 100644 index 0000000000..e723ce3cc8 --- /dev/null +++ b/plugins/ac3_adec/Makefile @@ -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) $@ + diff --git a/src/ac3_decoder/ac3_decoder_thread.c b/plugins/ac3_adec/ac3_adec.c similarity index 77% rename from src/ac3_decoder/ac3_decoder_thread.c rename to plugins/ac3_adec/ac3_adec.c index 667d83ed6c..1559b04e3a 100644 --- a/src/ac3_decoder/ac3_decoder_thread.c +++ b/plugins/ac3_adec/ac3_adec.c @@ -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 * @@ -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 + *****************************************************************************/ +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 *****************************************************************************/ -vlc_thread_t ac3dec_CreateThread( adec_config_t * p_config ) +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,15 +137,110 @@ 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; + if( ac3_adec_Init( p_ac3thread ) ) + { + intf_ErrMsg( "ac3_adec error : could not initialize thread" ); + return( -1 ); + } + + sync = 0; + p_ac3thread->sync_ptr = 0; + + /* ac3 decoder thread's main loop */ + /* FIXME : do we have enough room to store the decoded frames ?? */ + while ((!p_ac3thread->p_fifo->b_die) && (!p_ac3thread->p_fifo->b_error)) + { + s16 * buffer; + ac3_sync_info_t sync_info; + int ptr; + + if (!sync) { + do { + GetBits(&p_ac3thread->ac3_decoder->bit_stream,8); + } while ((!p_ac3thread->sync_ptr) && (!p_ac3thread->p_fifo->b_die) + && (!p_ac3thread->p_fifo->b_error)); + + ptr = p_ac3thread->sync_ptr; + + while(ptr-- && (!p_ac3thread->p_fifo->b_die) + && (!p_ac3thread->p_fifo->b_error)) + { + p_ac3thread->ac3_decoder->bit_stream.p_byte++; + } + + /* we are in sync now */ + sync = 1; + } + + if (DECODER_FIFO_START(*p_ac3thread->p_fifo)->i_pts) + { + 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] = + LAST_MDATE; + } + + if (ac3_sync_frame (p_ac3thread->ac3_decoder, &sync_info)) + { + sync = 0; + goto bad_frame; + } + + p_ac3thread->p_aout_fifo->l_rate = sync_info.sample_rate; + + buffer = ((s16 *)p_ac3thread->p_aout_fifo->buffer) + + (p_ac3thread->p_aout_fifo->l_end_frame * AC3DEC_FRAME_SIZE); + + if (ac3_decode_frame (p_ac3thread->ac3_decoder, buffer)) + { + sync = 0; + goto bad_frame; + } + + vlc_mutex_lock (&p_ac3thread->p_aout_fifo->data_lock); + p_ac3thread->p_aout_fifo->l_end_frame = + (p_ac3thread->p_aout_fifo->l_end_frame + 1) & AOUT_FIFO_SIZE; + vlc_cond_signal (&p_ac3thread->p_aout_fifo->data_wait); + vlc_mutex_unlock (&p_ac3thread->p_aout_fifo->data_lock); + + bad_frame: + RealignBits(&p_ac3thread->ac3_decoder->bit_stream); + } + + /* If b_error is set, the ac3 decoder thread enters the error loop */ + if (p_ac3thread->p_fifo->b_error) + { + ac3_adec_ErrorThread (p_ac3thread); + } + + /* End of the ac3 decoder thread */ + ac3_adec_EndThread (p_ac3thread); + + return( 0 ); +} + + +/***************************************************************************** + * ac3_adec_Init: initialize data before entering main loop + *****************************************************************************/ +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)); /* @@ -109,7 +254,7 @@ vlc_thread_t ac3dec_CreateThread( adec_config_t * p_config ) intf_ErrMsg( "ac3dec error: no suitable downmix module" ); free( p_ac3thread->ac3_decoder ); free( p_ac3thread ); - return( 0 ); + return( -1 ); } #define F DOWNMIX.p_module->p_functions->downmix.functions.downmix @@ -138,7 +283,7 @@ vlc_thread_t ac3dec_CreateThread( adec_config_t * p_config ) free( p_ac3thread->ac3_decoder->imdct ); free( p_ac3thread->ac3_decoder ); free( p_ac3thread ); - return( 0 ); + return( -1 ); } #define F IMDCT->p_module->p_functions->imdct.functions.imdct @@ -152,10 +297,12 @@ vlc_thread_t ac3dec_CreateThread( adec_config_t * p_config ) /* 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); + 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)); + 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)); @@ -180,164 +327,35 @@ vlc_thread_t ac3dec_CreateThread( adec_config_t * p_config ) */ 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 ( "ac3_adec debug: ac3_adec thread (%p) initialized", + p_ac3thread ); - 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( + /* + * Bit stream + */ + p_ac3thread->p_config->pf_init_bit_stream( &p_ac3thread->ac3_decoder->bit_stream, - p_ac3thread->p_config->decoder_config.p_decoder_fifo, + 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; + 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; - } - - sync = 0; - p_ac3thread->sync_ptr = 0; - - /* ac3 decoder thread's main loop */ - /* FIXME : do we have enough room to store the decoded frames ?? */ - while ((!p_ac3thread->p_fifo->b_die) && (!p_ac3thread->p_fifo->b_error)) - { - s16 * buffer; - ac3_sync_info_t sync_info; - int ptr; - - if (!sync) { - do { - GetBits(&p_ac3thread->ac3_decoder->bit_stream,8); - } while ((!p_ac3thread->sync_ptr) && (!p_ac3thread->p_fifo->b_die) - && (!p_ac3thread->p_fifo->b_error)); - - ptr = p_ac3thread->sync_ptr; - - while(ptr-- && (!p_ac3thread->p_fifo->b_die) - && (!p_ac3thread->p_fifo->b_error)) - { - p_ac3thread->ac3_decoder->bit_stream.p_byte++; - } - - /* we are in sync now */ - sync = 1; - } - - if (DECODER_FIFO_START(*p_ac3thread->p_fifo)->i_pts) - { - 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] = - LAST_MDATE; - } - if (ac3_sync_frame (p_ac3thread->ac3_decoder, &sync_info)) - { - sync = 0; - goto bad_frame; - } - - p_ac3thread->p_aout_fifo->l_rate = sync_info.sample_rate; - - buffer = ((s16 *)p_ac3thread->p_aout_fifo->buffer) + - (p_ac3thread->p_aout_fifo->l_end_frame * AC3DEC_FRAME_SIZE); - - if (ac3_decode_frame (p_ac3thread->ac3_decoder, buffer)) - { - sync = 0; - goto bad_frame; - } - - vlc_mutex_lock (&p_ac3thread->p_aout_fifo->data_lock); - p_ac3thread->p_aout_fifo->l_end_frame = - (p_ac3thread->p_aout_fifo->l_end_frame + 1) & AOUT_FIFO_SIZE; - vlc_cond_signal (&p_ac3thread->p_aout_fifo->data_wait); - vlc_mutex_unlock (&p_ac3thread->p_aout_fifo->data_lock); - - bad_frame: - RealignBits(&p_ac3thread->ac3_decoder->bit_stream); - } - - /* If b_error is set, the ac3 decoder thread enters the error loop */ - if (p_ac3thread->p_fifo->b_error) - { - ErrorThread (p_ac3thread); - } - - /* End of the ac3 decoder thread */ - EndThread (p_ac3thread); + return( 0 ); } + /***************************************************************************** - * ErrorThread : ac3 decoder's RunThread() error loop + * ac3_adec_ErrorThread : ac3 decoder's RunThread() error loop *****************************************************************************/ -static void ErrorThread (ac3dec_thread_t * p_ac3thread) +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); diff --git a/src/ac3_decoder/ac3_decoder_thread.h b/plugins/ac3_adec/ac3_adec.h similarity index 89% rename from src/ac3_decoder/ac3_decoder_thread.h rename to plugins/ac3_adec/ac3_adec.h index 600a255516..6ea6a88c0d 100644 --- a/src/ac3_decoder/ac3_decoder_thread.h +++ b/plugins/ac3_adec/ac3_adec.h @@ -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 * @@ -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 ); diff --git a/src/ac3_decoder/ac3_bit_allocate.c b/plugins/ac3_adec/ac3_bit_allocate.c similarity index 99% rename from src/ac3_decoder/ac3_bit_allocate.c rename to plugins/ac3_adec/ac3_bit_allocate.c index 2e1db36ab7..b0eb9491c9 100644 --- a/src/ac3_decoder/ac3_bit_allocate.c +++ b/plugins/ac3_adec/ac3_bit_allocate.c @@ -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 * Aaron Holtzman diff --git a/src/ac3_decoder/ac3_decoder.c b/plugins/ac3_adec/ac3_decoder.c similarity index 96% rename from src/ac3_decoder/ac3_decoder.c rename to plugins/ac3_adec/ac3_decoder.c index 99db0767f4..ecf9fc5805 100644 --- a/src/ac3_decoder/ac3_decoder.c +++ b/plugins/ac3_adec/ac3_decoder.c @@ -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 * Michel Lespinasse @@ -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" diff --git a/src/ac3_decoder/ac3_decoder.h b/plugins/ac3_adec/ac3_decoder.h similarity index 99% rename from src/ac3_decoder/ac3_decoder.h rename to plugins/ac3_adec/ac3_decoder.h index c6740bc519..d68b943fc0 100644 --- a/src/ac3_decoder/ac3_decoder.h +++ b/plugins/ac3_adec/ac3_decoder.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 * Renaud Dartus diff --git a/src/ac3_decoder/ac3_exponent.c b/plugins/ac3_adec/ac3_exponent.c similarity index 97% rename from src/ac3_decoder/ac3_exponent.c rename to plugins/ac3_adec/ac3_exponent.c index f9bb5c4cee..d1cb1f3e6b 100644 --- a/src/ac3_decoder/ac3_exponent.c +++ b/plugins/ac3_adec/ac3_exponent.c @@ -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 * Michel Lespinasse @@ -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" diff --git a/src/ac3_decoder/ac3_exponent.h b/plugins/ac3_adec/ac3_exponent.h similarity index 98% rename from src/ac3_decoder/ac3_exponent.h rename to plugins/ac3_adec/ac3_exponent.h index cb8a514cb2..957e71899f 100644 --- a/src/ac3_decoder/ac3_exponent.h +++ b/plugins/ac3_adec/ac3_exponent.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 * Michel Lespinasse diff --git a/src/ac3_decoder/ac3_imdct.c b/plugins/ac3_adec/ac3_imdct.c similarity index 99% rename from src/ac3_decoder/ac3_imdct.c rename to plugins/ac3_adec/ac3_imdct.c index 01287bda4f..7b30b0812a 100644 --- a/src/ac3_decoder/ac3_imdct.c +++ b/plugins/ac3_adec/ac3_imdct.c @@ -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 * Aaron Holtzman diff --git a/src/ac3_decoder/ac3_internal.h b/plugins/ac3_adec/ac3_internal.h similarity index 96% rename from src/ac3_decoder/ac3_internal.h rename to plugins/ac3_adec/ac3_internal.h index 08419cf2cf..3768304b12 100644 --- a/src/ac3_decoder/ac3_internal.h +++ b/plugins/ac3_adec/ac3_internal.h @@ -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 * diff --git a/src/ac3_decoder/ac3_mantissa.c b/plugins/ac3_adec/ac3_mantissa.c similarity index 97% rename from src/ac3_decoder/ac3_mantissa.c rename to plugins/ac3_adec/ac3_mantissa.c index ffc80f6258..5e05d7e75a 100644 --- a/src/ac3_decoder/ac3_mantissa.c +++ b/plugins/ac3_adec/ac3_mantissa.c @@ -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 * Aaron Holtzman @@ -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" diff --git a/src/ac3_decoder/ac3_mantissa.h b/plugins/ac3_adec/ac3_mantissa.h similarity index 99% rename from src/ac3_decoder/ac3_mantissa.h rename to plugins/ac3_adec/ac3_mantissa.h index cb6a32ff87..4d03d6394b 100644 --- a/src/ac3_decoder/ac3_mantissa.h +++ b/plugins/ac3_adec/ac3_mantissa.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 * Aaron Holtzman diff --git a/src/ac3_decoder/ac3_parse.c b/plugins/ac3_adec/ac3_parse.c similarity index 99% rename from src/ac3_decoder/ac3_parse.c rename to plugins/ac3_adec/ac3_parse.c index e6d1c06d13..7c58c5a1c4 100644 --- a/src/ac3_decoder/ac3_parse.c +++ b/plugins/ac3_adec/ac3_parse.c @@ -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 * Aaron Holtzman @@ -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 */ diff --git a/src/ac3_decoder/ac3_rematrix.c b/plugins/ac3_adec/ac3_rematrix.c similarity index 97% rename from src/ac3_decoder/ac3_rematrix.c rename to plugins/ac3_adec/ac3_rematrix.c index 11be6a7c3b..c2a5f750c7 100644 --- a/src/ac3_decoder/ac3_rematrix.c +++ b/plugins/ac3_adec/ac3_rematrix.c @@ -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 * Aaron Holtzman diff --git a/plugins/ac3_spdif/Makefile b/plugins/ac3_spdif/Makefile new file mode 100644 index 0000000000..2d71b5a899 --- /dev/null +++ b/plugins/ac3_spdif/Makefile @@ -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) $@ + diff --git a/src/ac3_spdif/ac3_iec958.c b/plugins/ac3_spdif/ac3_iec958.c similarity index 98% rename from src/ac3_spdif/ac3_iec958.c rename to plugins/ac3_spdif/ac3_iec958.c index 7cb91b0afd..595ac77143 100644 --- a/src/ac3_spdif/ac3_iec958.c +++ b/plugins/ac3_spdif/ac3_iec958.c @@ -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 * Juha Yrjola @@ -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" diff --git a/src/ac3_spdif/ac3_iec958.h b/plugins/ac3_spdif/ac3_iec958.h similarity index 97% rename from src/ac3_spdif/ac3_iec958.h rename to plugins/ac3_spdif/ac3_iec958.h index 502ce3f27c..5f71939070 100644 --- a/src/ac3_spdif/ac3_iec958.h +++ b/plugins/ac3_spdif/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 * Juha Yrjola diff --git a/src/ac3_spdif/ac3_spdif.c b/plugins/ac3_spdif/ac3_spdif.c similarity index 76% rename from src/ac3_spdif/ac3_spdif.c rename to plugins/ac3_spdif/ac3_spdif.c index fa531afd1a..72a81daa72 100644 --- a/src/ac3_spdif/ac3_spdif.c +++ b/plugins/ac3_spdif/ac3_spdif.c @@ -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 * Juha Yrjola @@ -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,152 +62,96 @@ /**************************************************************************** * 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 ); -/**************************************************************************** - * spdif_CreateThread: initialize the spdif thread - ****************************************************************************/ -vlc_thread_t spdif_CreateThread( adec_config_t * p_config ) +/***************************************************************************** + * Capabilities + *****************************************************************************/ +void _M( adec_getfunctions )( function_list_t * p_function_list ) { - ac3_spdif_thread_t * p_spdif; - - intf_DbgMsg( "spdif debug: creating ac3 pass-through thread" ); - - /* Allocate the memory needed to store the thread's structure */ - p_spdif = malloc( sizeof(ac3_spdif_thread_t) ); - - if( p_spdif == NULL ) - { - intf_ErrMsg ( "spdif error: not enough memory " - "for spdif_CreateThread() to create the new thread"); - return 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 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; + p_function_list->pf_probe = ac3_spdif_Probe; + p_function_list->functions.dec.pf_RunThread = ac3_spdif_Run; } -/* - * 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; - } +/***************************************************************************** + * Build configuration tree. + *****************************************************************************/ +MODULE_CONFIG_START +ADD_WINDOW( "Configuration for ac3 spdif decoder module" ) + ADD_COMMENT( "Nothing to configure" ) +MODULE_CONFIG_STOP - /* 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"); +MODULE_INIT_START + p_module->i_capabilities = MODULE_CAPABILITY_DEC; + p_module->psz_longname = "Ac3 SPDIF decoder for AC3 pass-through"; +MODULE_INIT_STOP - aout_DestroyFifo( p_spdif->p_aout_fifo ); - return -1; - } - p_spdif->p_aout_fifo->l_rate = p_spdif->ac3_info.i_sample_rate; +MODULE_ACTIVATE_START + _M( adec_getfunctions )( &p_module->p_functions->dec ); +MODULE_ACTIVATE_STOP - GetChunk( &p_spdif->bit_stream, p_spdif->p_ac3 + sizeof(sync_frame_t), - p_spdif->ac3_info.i_frame_size - sizeof(sync_frame_t) ); +MODULE_DEACTIVATE_START +MODULE_DEACTIVATE_STOP - return 0; +/***************************************************************************** + * 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 ); } + /**************************************************************************** - * RunThread: loop that reads ac3 ES and transform it to - * an spdif compliant stream. + * ac3_spdif_Run: the whole thing + **************************************************************************** + * This function is called just after the thread is launched. ****************************************************************************/ -static void RunThread( ac3_spdif_thread_t * p_spdif ) +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; - /* Initializing the spdif decoder thread */ - if( InitThread( p_spdif ) ) + 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) ); + + if( p_spdif == NULL ) + { + intf_ErrMsg ( "spdif error: not enough memory " + "for spdif_CreateThread() to create the new thread"); + return( -1 ); + } + + p_spdif->p_config = p_config; + + if (ac3_spdif_Init( 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 ); + 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 ); - return; + 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 ); } diff --git a/src/ac3_spdif/ac3_spdif.h b/plugins/ac3_spdif/ac3_spdif.h similarity index 87% rename from src/ac3_spdif/ac3_spdif.h rename to plugins/ac3_spdif/ac3_spdif.h index 7dacdd8099..fd198a870a 100644 --- a/src/ac3_spdif/ac3_spdif.h +++ b/plugins/ac3_spdif/ac3_spdif.h @@ -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 * @@ -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 ); - diff --git a/plugins/lpcm_adec/Makefile b/plugins/lpcm_adec/Makefile new file mode 100644 index 0000000000..e35b52409c --- /dev/null +++ b/plugins/lpcm_adec/Makefile @@ -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) $@ + diff --git a/src/lpcm_decoder/lpcm_decoder_thread.c b/plugins/lpcm_adec/lpcm_adec.c similarity index 54% rename from src/lpcm_decoder/lpcm_decoder_thread.c rename to plugins/lpcm_adec/lpcm_adec.c index 22f1de64fe..bf80686a60 100644 --- a/src/lpcm_decoder/lpcm_decoder_thread.c +++ b/plugins/lpcm_adec/lpcm_adec.c @@ -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 * Henri Fallon @@ -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; + if( lpcm_adec_Init( p_lpcmdec ) ) + { + return( -1 ); + } - /* Spawn the lpcm decoder thread */ - if( vlc_thread_create( &p_lpcmdec->thread_id, "lpcm decoder", - (vlc_thread_func_t)RunThread, (void *)p_lpcmdec ) ) + 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)) { - intf_ErrMsg( "LPCM : error : cannot spawn thread" ); - free (p_lpcmdec); - return 0; + lpcm_adec_DecodeFrame(p_lpcmdec); } - intf_DbgMsg( "LPCM Debug: lpcm decoder thread (%p) created\n", p_lpcmdec ); - return p_lpcmdec->thread_id; -} + /* 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); + } -/* Following functions are local */ + /* End of the lpcm decoder thread */ + lpcm_adec_EndThread (p_lpcmdec); + + return( 0 ); +} /***************************************************************************** - * 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; - - 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); - 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) ; - 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 ); - + /* 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); } - - /* If b_error is set, the lpcm decoder thread enters the error loop */ - if (p_lpcmdec->p_fifo->b_error) + + GetChunk( &p_lpcmdec->bit_stream, p_temp, LPCMDEC_FRAME_SIZE); + + for( i_loop = 0; i_loop < LPCMDEC_FRAME_SIZE/2; i_loop++ ) { - ErrorThread (p_lpcmdec); + 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 ); diff --git a/src/lpcm_decoder/lpcm_decoder_thread.h b/plugins/lpcm_adec/lpcm_adec.h similarity index 92% rename from src/lpcm_decoder/lpcm_decoder_thread.h rename to plugins/lpcm_adec/lpcm_adec.h index e0eacc0b4c..6f5f0d970c 100644 --- a/src/lpcm_decoder/lpcm_decoder_thread.h +++ b/plugins/lpcm_adec/lpcm_adec.h @@ -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 * @@ -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 ); diff --git a/plugins/mpeg_adec/Makefile b/plugins/mpeg_adec/Makefile new file mode 100644 index 0000000000..60636ad98d --- /dev/null +++ b/plugins/mpeg_adec/Makefile @@ -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) $@ + diff --git a/src/audio_decoder/adec_layer1.c b/plugins/mpeg_adec/adec_layer1.c similarity index 98% rename from src/audio_decoder/adec_layer1.c rename to plugins/mpeg_adec/adec_layer1.c index 0cae8a4899..29c23451b8 100644 --- a/src/audio_decoder/adec_layer1.c +++ b/plugins/mpeg_adec/adec_layer1.c @@ -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 * Michel Lespinasse @@ -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 ****/ diff --git a/src/audio_decoder/adec_layer1.h b/plugins/mpeg_adec/adec_layer1.h similarity index 95% rename from src/audio_decoder/adec_layer1.h rename to plugins/mpeg_adec/adec_layer1.h index 9bace6e7a0..c2c36aa4d4 100644 --- a/src/audio_decoder/adec_layer1.h +++ b/plugins/mpeg_adec/adec_layer1.h @@ -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 * diff --git a/src/audio_decoder/adec_layer2.c b/plugins/mpeg_adec/adec_layer2.c similarity index 99% rename from src/audio_decoder/adec_layer2.c rename to plugins/mpeg_adec/adec_layer2.c index 70aa0eb7b1..1bd3ee86c5 100644 --- a/src/audio_decoder/adec_layer2.c +++ b/plugins/mpeg_adec/adec_layer2.c @@ -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 * Michel Lespinasse @@ -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 ****/ diff --git a/src/audio_decoder/adec_layer2.h b/plugins/mpeg_adec/adec_layer2.h similarity index 95% rename from src/audio_decoder/adec_layer2.h rename to plugins/mpeg_adec/adec_layer2.h index 1e53da0cf9..e1d183b9fa 100644 --- a/src/audio_decoder/adec_layer2.h +++ b/plugins/mpeg_adec/adec_layer2.h @@ -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 * diff --git a/src/audio_decoder/adec_math.c b/plugins/mpeg_adec/adec_math.c similarity index 99% rename from src/audio_decoder/adec_math.c rename to plugins/mpeg_adec/adec_math.c index 13f542b745..a68092fa03 100644 --- a/src/audio_decoder/adec_math.c +++ b/plugins/mpeg_adec/adec_math.c @@ -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 * Michel Lespinasse @@ -23,7 +23,7 @@ *****************************************************************************/ #include "int_types.h" -#include "adec_generic.h" +#include "mpeg_adec_generic.h" /***************************************************************************** * DCT32: Fast 32 points Discrete Cosine Transform diff --git a/src/audio_decoder/adec_math.h b/plugins/mpeg_adec/adec_math.h similarity index 95% rename from src/audio_decoder/adec_math.h rename to plugins/mpeg_adec/adec_math.h index b3ab5bd7ba..14e34222e0 100644 --- a/src/audio_decoder/adec_math.h +++ b/plugins/mpeg_adec/adec_math.h @@ -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 * diff --git a/src/audio_decoder/adec_test.c b/plugins/mpeg_adec/adec_test.c similarity index 96% rename from src/audio_decoder/adec_test.c rename to plugins/mpeg_adec/adec_test.c index 4e9b7f1521..6b729ef95b 100644 --- a/src/audio_decoder/adec_test.c +++ b/plugins/mpeg_adec/adec_test.c @@ -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 * Michel Lespinasse @@ -38,8 +38,8 @@ #include #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) diff --git a/src/audio_decoder/audio_decoder.c b/plugins/mpeg_adec/mpeg_adec.c similarity index 54% rename from src/audio_decoder/audio_decoder.c rename to plugins/mpeg_adec/mpeg_adec.c index e06f6c2d21..a2cc0c509b 100644 --- a/src/audio_decoder/audio_decoder.c +++ b/plugins/mpeg_adec/mpeg_adec.c @@ -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 * Michel Lespinasse @@ -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 /* getpid() */ -#endif - -#include /* "intf_msg.h" */ -#include /* memcpy(), memset() */ #include /* 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" + +#include "audio_output.h" /* aout_fifo_t (for audio_decoder.h) */ + +#include "modules.h" +#include "modules_export.h" -#include "intf_msg.h" /* intf_DbgMsg(), intf_ErrMsg() */ - #include "stream_control.h" #include "input_ext-dec.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 "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; +} + +/***************************************************************************** + * 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 - intf_DbgMsg ( "adec debug: creating audio decoder thread" ); +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) ) + /* 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 ) { - intf_ErrMsg ("adec error: can't spawn audio decoder thread"); - free (p_adec); - return 0; + intf_ErrMsg("mpeg_adec error: cannot create audio output fifo"); + return -1; } - intf_DbgMsg ("adec debug: audio decoder thread (%p) created", p_adec); - return p_adec->thread_id; -} - -/* following functions are local */ + intf_DbgMsg("mpeg_adec debug: thread initialized, decoding begins."); -/***************************************************************************** - * 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 ); + p_adec->i_sync = 0; - /* Creating 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 ) + /* Audio decoder thread's main loop */ + while( (!p_adec->p_fifo->b_die) && (!p_adec->p_fifo->b_error) ) { - return -1; + adec_Decode( p_adec ); + } + + /* If b_error is set, the audio decoder thread enters the error loop */ + if( p_adec->p_fifo->b_error ) + { + adec_ErrorThread( p_adec ); } - intf_DbgMsg ( "adec debug: audio decoder thread %p initialized", p_adec ); - return 0; + /* End of the audio decoder thread */ + adec_EndThread( p_adec ); + + return( 0 ); } +/* + * Following finctions are local to this module + */ + /***************************************************************************** - * RunThread : audio decoder thread - ***************************************************************************** - * Audio decoder thread. This function does only returns when the thread is - * terminated. + * adec_Decode: decodes a mpeg frame *****************************************************************************/ -static void RunThread (adec_thread_t * p_adec) +static void adec_Decode( adec_thread_t * p_adec ) { - int sync; + s16 * buffer; + adec_sync_info_t sync_info; - intf_DbgMsg ( "adec debug: running audio decoder thread (%p) (pid == %i)", - p_adec, getpid() ); + if( ! adec_SyncFrame (p_adec, &sync_info) ) + { + p_adec->i_sync = 1; - /* Initializing the audio decoder thread */ - p_adec->p_fifo->b_error = InitThread (p_adec); + p_adec->p_aout_fifo->l_rate = sync_info.sample_rate; - sync = 0; + buffer = ((s16 *)p_adec->p_aout_fifo->buffer) + + (p_adec->p_aout_fifo->l_end_frame * ADEC_FRAME_SIZE); - /* 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( 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_SyncFrame (p_adec, &sync_info) ) + if( adec_DecodeFrame (p_adec, buffer) ) { - 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); - } + /* Ouch, failed decoding... We'll have to resync */ + p_adec->i_sync = 0; } - } + else + { + vlc_mutex_lock (&p_adec->p_aout_fifo->data_lock); - /* If b_error is set, the audio decoder thread enters the error loop */ - if( p_adec->p_fifo->b_error ) - { - ErrorThread( p_adec ); + 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); + } } - - /* End of the audio decoder thread */ - EndThread( p_adec ); } /***************************************************************************** - * 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 ); diff --git a/src/audio_decoder/audio_decoder.h b/plugins/mpeg_adec/mpeg_adec.h similarity index 77% rename from src/audio_decoder/audio_decoder.h rename to plugins/mpeg_adec/mpeg_adec.h index 07e93bb302..0f21100171 100644 --- a/src/audio_decoder/audio_decoder.h +++ b/plugins/mpeg_adec/mpeg_adec.h @@ -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 * @@ -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 * ); diff --git a/src/audio_decoder/adec_generic.c b/plugins/mpeg_adec/mpeg_adec_generic.c similarity index 96% rename from src/audio_decoder/adec_generic.c rename to plugins/mpeg_adec/mpeg_adec_generic.c index 8aa6a00e2c..ccf41605b4 100644 --- a/src/audio_decoder/adec_generic.c +++ b/plugins/mpeg_adec/mpeg_adec_generic.c @@ -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 * Michel Lespinasse @@ -30,11 +30,15 @@ #include "common.h" #include "threads.h" #include "mtime.h" -#include "stream_control.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 "adec_generic.h" -#include "audio_decoder.h" +#include "mpeg_adec_generic.h" +#include "mpeg_adec.h" #include "adec_math.h" /* DCT32(), PCM() */ #include "adec_layer1.h" #include "adec_layer2.h" diff --git a/src/audio_decoder/adec_generic.h b/plugins/mpeg_adec/mpeg_adec_generic.h similarity index 95% rename from src/audio_decoder/adec_generic.h rename to plugins/mpeg_adec/mpeg_adec_generic.h index ec3636f782..da795ae6ff 100644 --- a/src/audio_decoder/adec_generic.h +++ b/plugins/mpeg_adec/mpeg_adec_generic.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 * @@ -40,3 +40,4 @@ typedef struct adec_bank_s } adec_bank_t; + diff --git a/plugins/mpeg_vdec/Makefile b/plugins/mpeg_vdec/Makefile new file mode 100644 index 0000000000..7857659b4b --- /dev/null +++ b/plugins/mpeg_vdec/Makefile @@ -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) $@ + diff --git a/src/video_decoder/video_decoder.c b/plugins/mpeg_vdec/video_decoder.c similarity index 99% rename from src/video_decoder/video_decoder.c rename to plugins/mpeg_vdec/video_decoder.c index 9bf727ab81..9a7cde550d 100644 --- a/src/video_decoder/video_decoder.c +++ b/plugins/mpeg_vdec/video_decoder.c @@ -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 * Michel Lespinasse @@ -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" diff --git a/src/video_decoder/video_decoder.h b/plugins/mpeg_vdec/video_decoder.h similarity index 96% rename from src/video_decoder/video_decoder.h rename to plugins/mpeg_vdec/video_decoder.h index 985684ceff..e672f23c92 100644 --- a/src/video_decoder/video_decoder.h +++ b/plugins/mpeg_vdec/video_decoder.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 * diff --git a/src/video_decoder/video_parser.c b/plugins/mpeg_vdec/video_parser.c similarity index 81% rename from src/video_decoder/video_parser.c rename to plugins/mpeg_vdec/video_parser.c index b443b113d1..e9d59de109 100644 --- a/src/video_decoder/video_parser.c +++ b/plugins/mpeg_vdec/video_parser.c @@ -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 * Samuel Hocevar @@ -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 ); + +/***************************************************************************** + * Capabilities + *****************************************************************************/ +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 + /***************************************************************************** - * vpar_CreateThread: create a generic parser thread + * mpeg_vdec_Probe: probe the decoder and return score ***************************************************************************** - * This function creates a new video parser thread, and returns a pointer - * to its description. On error, it returns NULL. + * 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 *****************************************************************************/ -vlc_thread_t vpar_CreateThread( vdec_config_t * p_config ) +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 ); + } + + /* End of thread */ + mpeg_vdec_EndThread( p_vpar ); -/* following functions are local */ + 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); diff --git a/src/video_decoder/video_parser.h b/plugins/mpeg_vdec/video_parser.h similarity index 99% rename from src/video_decoder/video_parser.h rename to plugins/mpeg_vdec/video_parser.h index a86784d2ba..2e4cc3c2c5 100644 --- a/src/video_decoder/video_parser.h +++ b/plugins/mpeg_vdec/video_parser.h @@ -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 * Jean-Marc Dressler @@ -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 */ diff --git a/src/video_decoder/vpar_blocks.c b/plugins/mpeg_vdec/vpar_blocks.c similarity index 99% rename from src/video_decoder/vpar_blocks.c rename to plugins/mpeg_vdec/vpar_blocks.c index 6ce7faec47..79b9228614 100644 --- a/src/video_decoder/vpar_blocks.c +++ b/plugins/mpeg_vdec/vpar_blocks.c @@ -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 * Aaron Holtzman @@ -34,14 +34,15 @@ #include "common.h" #include "threads.h" #include "mtime.h" - #include "intf_msg.h" +#include "video.h" +#include "video_output.h" + +#include "modules_export.h" #include "stream_control.h" #include "input_ext-dec.h" -#include "video.h" -#include "video_output.h" #include "vdec_ext-plugins.h" #include "vpar_pool.h" diff --git a/src/video_decoder/vpar_blocks.h b/plugins/mpeg_vdec/vpar_blocks.h similarity index 99% rename from src/video_decoder/vpar_blocks.h rename to plugins/mpeg_vdec/vpar_blocks.h index f03dd138eb..35f17474a6 100644 --- a/src/video_decoder/vpar_blocks.h +++ b/plugins/mpeg_vdec/vpar_blocks.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 * Jean-Marc Dressler diff --git a/src/video_decoder/vpar_headers.c b/plugins/mpeg_vdec/vpar_headers.c similarity index 99% rename from src/video_decoder/vpar_headers.c rename to plugins/mpeg_vdec/vpar_headers.c index 0198fde082..3e860c6dec 100644 --- a/src/video_decoder/vpar_headers.c +++ b/plugins/mpeg_vdec/vpar_headers.c @@ -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 * Stéphane Borel @@ -34,14 +34,15 @@ #include "common.h" #include "threads.h" #include "mtime.h" - #include "intf_msg.h" +#include "video.h" +#include "video_output.h" + +#include "modules_export.h" #include "stream_control.h" #include "input_ext-dec.h" -#include "video.h" -#include "video_output.h" #include "vdec_ext-plugins.h" #include "vpar_pool.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 ) { diff --git a/src/video_decoder/vpar_pool.c b/plugins/mpeg_vdec/vpar_pool.c similarity index 98% rename from src/video_decoder/vpar_pool.c rename to plugins/mpeg_vdec/vpar_pool.c index 4490cc7db2..e1fb4cfe7a 100644 --- a/src/video_decoder/vpar_pool.c +++ b/plugins/mpeg_vdec/vpar_pool.c @@ -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 * @@ -33,14 +33,15 @@ #include "common.h" #include "threads.h" #include "mtime.h" - #include "intf_msg.h" +#include "video.h" +#include "video_output.h" + +#include "modules_export.h" #include "stream_control.h" #include "input_ext-dec.h" -#include "video.h" -#include "video_output.h" #include "vdec_ext-plugins.h" #include "vpar_pool.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 ); diff --git a/src/video_decoder/vpar_pool.h b/plugins/mpeg_vdec/vpar_pool.h similarity index 98% rename from src/video_decoder/vpar_pool.h rename to plugins/mpeg_vdec/vpar_pool.h index 1b3741065d..672b9a2af4 100644 --- a/src/video_decoder/vpar_pool.h +++ b/plugins/mpeg_vdec/vpar_pool.h @@ -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 * diff --git a/src/video_decoder/vpar_synchro.c b/plugins/mpeg_vdec/vpar_synchro.c similarity index 99% rename from src/video_decoder/vpar_synchro.c rename to plugins/mpeg_vdec/vpar_synchro.c index c7b2ca98ea..e431cec039 100644 --- a/src/video_decoder/vpar_synchro.c +++ b/plugins/mpeg_vdec/vpar_synchro.c @@ -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 * Samuel Hocevar @@ -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 diff --git a/plugins/spu_dec/Makefile b/plugins/spu_dec/Makefile new file mode 100644 index 0000000000..0688a3537c --- /dev/null +++ b/plugins/spu_dec/Makefile @@ -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) $@ + diff --git a/src/spu_decoder/spu_decoder.c b/plugins/spu_dec/spu_decoder.c similarity index 89% rename from src/spu_decoder/spu_decoder.c rename to plugins/spu_dec/spu_decoder.c index be9b49f949..2993355c8a 100644 --- a/src/spu_decoder/spu_decoder.c +++ b/plugins/spu_dec/spu_decoder.c @@ -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 * @@ -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,16 +129,64 @@ 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; + p_spudec->p_fifo = p_config->p_decoder_fifo; + + /* + * Initialize thread and free configuration + */ + p_spudec->p_fifo->b_error = spu_dec_Init( p_spudec ); + + /* + * Main loop - it is not executed if an error occured during + * initialization + */ + while( (!p_spudec->p_fifo->b_die) && (!p_spudec->p_fifo->b_error) ) + { + if( !SyncPacket( p_spudec ) ) + { + ParsePacket( p_spudec ); + } + } + + /* + * Error loop + */ + if( p_spudec->p_fifo->b_error ) + { + spu_dec_ErrorThread( p_spudec ); + } + + /* End of thread */ + 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 ); @@ -105,7 +203,7 @@ vlc_thread_t spudec_CreateThread( vdec_config_t * p_config ) vlc_mutex_unlock( &p_vout_bank->lock ); free( p_spudec ); - return 0; + return( -1 ); } p_vout_bank->pp_vout[ p_vout_bank->i_count ] = p_spudec->p_vout; @@ -118,86 +216,22 @@ vlc_thread_t spudec_CreateThread( vdec_config_t * p_config ) } 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->p_config->pf_init_bit_stream( &p_spudec->bit_stream, - p_spudec->p_config->decoder_config.p_decoder_fifo, NULL, NULL ); + p_spudec->p_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() ); - - /* - * Initialize thread and free configuration - */ - p_spudec->p_fifo->b_error = InitThread( p_spudec ); - - /* - * Main loop - it is not executed if an error occured during - * initialization - */ - while( (!p_spudec->p_fifo->b_die) && (!p_spudec->p_fifo->b_error) ) - { - if( !SyncPacket( p_spudec ) ) - { - ParsePacket( p_spudec ); - } - } - - /* - * Error loop - */ - if( p_spudec->p_fifo->b_error ) - { - ErrorThread( p_spudec ); - } - - /* End of thread */ - intf_WarnMsg( 3, "spudec: destroying spu decoder thread %i", getpid() ); - EndThread( p_spudec ); -} - -/***************************************************************************** - * 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 ); diff --git a/src/spu_decoder/spu_decoder.h b/plugins/spu_dec/spu_decoder.h similarity index 95% rename from src/spu_decoder/spu_decoder.h rename to plugins/spu_dec/spu_decoder.h index 1611bd1093..d0ea3784a1 100644 --- a/src/spu_decoder/spu_decoder.h +++ b/plugins/spu_dec/spu_decoder.h @@ -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 * @@ -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 ); diff --git a/src/input/input_dec.c b/src/input/input_dec.c index eb53c05331..9947f116bb 100644 --- a/src/input/input_dec.c +++ b/src/input/input_dec.c @@ -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 * @@ -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 ) ) { diff --git a/src/input/input_programs.c b/src/input/input_programs.c index f2ef994251..e903a3efeb 100644 --- a/src/input/input_programs.c +++ b/src/input/input_programs.c @@ -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 * @@ -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; -- 2.39.2