diff options
Diffstat (limited to 'src/xine-engine')
30 files changed, 1064 insertions, 626 deletions
diff --git a/src/xine-engine/Makefile.am b/src/xine-engine/Makefile.am index 17dd96b10..36c48a3c9 100644 --- a/src/xine-engine/Makefile.am +++ b/src/xine-engine/Makefile.am @@ -1,47 +1,48 @@ include $(top_srcdir)/misc/Makefile.common include $(top_srcdir)/lib/Makefile.common -AM_CFLAGS = $(X_CFLAGS) $(FT2_CFLAGS) $(FONTCONFIG_CFLAGS) $(VISIBILITY_FLAG) -AM_CPPFLAGS = $(ZLIB_CPPFLAGS) -DXINE_LIBRARY_COMPILE +AM_CFLAGS = $(DEFAULT_OCFLAGS) $(X_CFLAGS) $(FT2_CFLAGS) $(FONTCONFIG_CFLAGS) $(VISIBILITY_FLAG) +AM_CPPFLAGS = $(XDG_BASEDIR_CPPFLAGS) $(ZLIB_CPPFLAGS) -DXINE_LIBRARY_COMPILE -LIBTOOL = $(SHELL) $(top_builddir)/libtool -lib_LTLIBRARIES = libxine.la +XINEUTILS_LIB = $(top_builddir)/src/xine-utils/libxineutils.la + +# FIXME: these are currently unused: +EXTRA_DIST = lrb.c lrb.h accel_xvmc.h -XINEUTILS_LIB = $(top_builddir)/src/xine-utils/libxineutils.la -DEF_FILE = libxine-$(XINE_MAJOR).def if WIN32 +DEF_FILE = libxine-$(XINE_MAJOR).def def_ldflags="-Wl,--output-def,$(DEF_FILE)" endif +noinst_HEADERS = bswap.h ffmpeg_bswap.h + +xineinclude_HEADERS = buffer.h metronom.h configfile.h vo_scale.h \ + audio_out.h resample.h video_out.h xine_internal.h spu_decoder.h \ + video_overlay.h osd.h spu.h scratch.h xine_plugin.h xineintl.h \ + plugin_catalog.h audio_decoder.h video_decoder.h post.h \ + io_helper.h broadcaster.h info_helper.h refcounter.h alphablend.h + +lib_LTLIBRARIES = libxine.la + libxine_la_SOURCES = xine.c metronom.c configfile.c buffer.c \ load_plugins.c video_decoder.c buffer_types.c \ audio_decoder.c video_out.c audio_out.c resample.c events.c \ - video_overlay.c osd.c scratch.c demux.c vo_scale.c \ + video_overlay.c osd.c spu.c scratch.c demux.c vo_scale.c \ xine_interface.c post.c tvmode.c broadcaster.c io_helper.c \ input_rip.c input_cache.c info_helper.c refcounter.c \ alphablend.c -# FIXME: these are currently unused: -EXTRA_DIST = lrb.c lrb.h accel_xvmc.h - -libxine_la_DEPENDENCIES = $(XINEUTILS_LIB) \ +libxine_la_DEPENDENCIES = $(XINEUTILS_LIB) $(XDG_BASEDIR_DEPS) \ $(pthread_dep) $(LIBXINEPOSIX) libxine_la_LIBADD = $(PTHREAD_LIBS) $(DYNAMIC_LD_LIBS) $(LTLIBINTL) $(ZLIB_LIBS) \ -lm $(XINEUTILS_LIB) $(LTLIBICONV) $(FT2_LIBS) $(FONTCONFIG_LIBS) \ - $(LIBXINEPOSIX) $(RT_LIBS) $(NET_LIBS) - -libxine_la_LDFLAGS = \ - -version-info $(XINE_LT_CURRENT):$(XINE_LT_REVISION):$(XINE_LT_AGE) \ - $(def_ldflags) + $(LIBXINEPOSIX) $(RT_LIBS) $(NET_LIBS) $(XDG_BASEDIR_LIBS) +libxine_la_LDFLAGS = $(AM_LDFLAGS) $(def_ldflags) \ + -version-info $(XINE_LT_CURRENT):$(XINE_LT_REVISION):$(XINE_LT_AGE) -xineinclude_HEADERS = buffer.h metronom.h configfile.h vo_scale.h \ - audio_out.h resample.h video_out.h xine_internal.h spu_decoder.h \ - video_overlay.h osd.h scratch.h xine_plugin.h xineintl.h \ - plugin_catalog.h audio_decoder.h video_decoder.h post.h \ - io_helper.h broadcaster.h info_helper.h refcounter.h alphablend.h - -noinst_HEADERS = bswap.h ffmpeg_bswap.h +$(XINEUTILS_LIB): + $(MAKE) -C $(top_builddir)/src/xine-utils libxineutils.la if WIN32 install-exec-local: @@ -50,6 +51,3 @@ install-exec-local: uninstall-local: rm -f $(DEF_FILE) endif - -$(XINEUTILS_LIB): - $(MAKE) -C $(top_builddir)/src/xine-utils libxineutils.la diff --git a/src/xine-engine/accel_xvmc.h b/src/xine-engine/accel_xvmc.h index cec5f9558..993f914bf 100644 --- a/src/xine-engine/accel_xvmc.h +++ b/src/xine-engine/accel_xvmc.h @@ -65,6 +65,7 @@ typedef struct xine_vld_frame_s { typedef struct xine_xvmc_s { + vo_frame_t *vo_frame; xine_macroblocks_t *macroblocks; void (*proc_macro_block)(int x,int y,int mb_type, int motion_type,int (*mv_field_sel)[2], @@ -74,6 +75,9 @@ typedef struct xine_xvmc_s { int second_field,int (*f_mot_pmv)[2],int (*b_mot_pmv)[2]); } xine_xvmc_t ; +#define XVMC_DATA(frame_gen) ((frame_gen) ? (xine_xvmc_t *)(frame_gen)->accel_data : (xine_xvmc_t *)0) +#define XVMC_FRAME(frame_gen) ((frame_gen) ? (xvmc_frame_t *)XVMC_DATA(frame_gen)->vo_frame : (xvmc_frame_t *)0) + typedef struct xine_xxmc_s { /* @@ -108,6 +112,9 @@ typedef struct xine_xxmc_s { void (*proc_xxmc_unlock) (vo_driver_t *this_gen); } xine_xxmc_t; +#define XXMC_DATA(frame_gen) ((frame_gen) ? (xine_xxmc_t *)(frame_gen)->accel_data : (xine_xxmc_t *)0) +#define XXMC_FRAME(frame_gen) ((frame_gen) ? (xxmc_frame_t *)XXMC_DATA(frame_gen)->xvmc.vo_frame : (xxmc_frame_t *)0) + /* * Register XvMC stream types here. */ diff --git a/src/xine-engine/alphablend.c b/src/xine-engine/alphablend.c index 8fcc4c469..4dffa09ad 100644 --- a/src/xine-engine/alphablend.c +++ b/src/xine-engine/alphablend.c @@ -1104,7 +1104,7 @@ static void blend_yuv_exact(uint8_t *dst_cr, uint8_t *dst_cb, int src_width, static uint8_t *(*blend_yuv_grow_extra_data(alphablend_t *extra_data, int osd_width))[ 3 ][ 2 ] { - struct __attribute__((packed)) header_s { + struct XINE_PACKED header_s { int id; int max_width; uint8_t *data[ 3 ][ 2 ]; @@ -1546,7 +1546,7 @@ static void blend_yuy2_exact(uint8_t *dst_cr, uint8_t *dst_cb, int src_width, static uint8_t *(*blend_yuy2_grow_extra_data(alphablend_t *extra_data, int osd_width))[ 3 ] { - struct __attribute__((packed)) header_s { + struct XINE_PACKED header_s { int id; int max_width; uint8_t *data[ 3 ]; diff --git a/src/xine-engine/alphablend.h b/src/xine-engine/alphablend.h index 3c9a693d9..f8c9ad540 100644 --- a/src/xine-engine/alphablend.h +++ b/src/xine-engine/alphablend.h @@ -39,37 +39,14 @@ typedef struct { void _x_alphablend_init(alphablend_t *extra_data, xine_t *xine) XINE_PROTECTED; void _x_alphablend_free(alphablend_t *extra_data) XINE_PROTECTED; -/* _MSC_VER port changes */ -#undef ATTRIBUTE_PACKED -#undef PRAGMA_PACK_BEGIN -#undef PRAGMA_PACK_END - -#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) || defined(__ICC) -#define ATTRIBUTE_PACKED __attribute__ ((packed)) -#define PRAGMA_PACK 0 -#endif - -#if !defined(ATTRIBUTE_PACKED) -#define ATTRIBUTE_PACKED -#define PRAGMA_PACK 1 -#endif - -#if PRAGMA_PACK -#pragma pack(8) -#endif - typedef struct { /* CLUT == Color LookUp Table */ uint8_t cb; uint8_t cr; uint8_t y; uint8_t foo; -} ATTRIBUTE_PACKED clut_t; +} XINE_PACKED clut_t; -#if PRAGMA_PACK -#pragma pack() -#endif - #define XX44_PALETTE_SIZE 32 typedef struct { diff --git a/src/xine-engine/audio_out.c b/src/xine-engine/audio_out.c index def102ef3..288e27672 100644 --- a/src/xine-engine/audio_out.c +++ b/src/xine-engine/audio_out.c @@ -16,14 +16,18 @@ * You should have received a copy of the GNU General Public License * along with self program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * 22-8-2001 James imported some useful AC3 sections from the previous alsa driver. - * (c) 2001 Andy Lo A Foe <andy@alsaplayer.org> - * 20-8-2001 First implementation of Audio sync and Audio driver separation. - * (c) 2001 James Courtier-Dutton James@superbug.demon.co.uk */ - -/* + +/** + * @file + * @brief xine-lib audio output implementation + * + * @date 2001-08-20 First implementation of Audio sync and Audio driver separation. + * (c) 2001 James Courtier-Dutton <james@superbug.demon.co.uk> + * @date 2001-08-22 James imported some useful AC3 sections from the previous + * ALSA driver. (c) 2001 Andy Lo A Foe <andy@alsaplayer.org> + * + * * General Programming Guidelines: - * New concept of an "audio_frame". * An audio_frame consists of all the samples required to fill every @@ -574,18 +578,16 @@ static void audio_filter_compress (aos_t *this, int16_t *mem, int num_frames) { } static void audio_filter_amp (aos_t *this, void *buf, int num_frames) { - - int i; - int num_channels; double amp_factor; - - num_channels = _x_ao_mode2channels (this->input.mode); - if (!num_channels) + int i; + const int total_frames = num_frames * _x_ao_mode2channels (this->input.mode); + + if (!total_frames) return; amp_factor=this->amp_factor; if (this->amp_mute || amp_factor == 0) { - memset (buf, 0, num_frames * num_channels * (this->input.bits / 8)); + memset (buf, 0, total_frames * (this->input.bits / 8)); return; } @@ -593,7 +595,7 @@ static void audio_filter_amp (aos_t *this, void *buf, int num_frames) { int16_t test; int8_t *mem = (int8_t *) buf; - for (i=0; i<num_frames*num_channels; i++) { + for (i=0; i<total_frames; i++) { test = mem[i] * amp_factor; /* Force limit on amp_factor to prevent clipping */ if (test < INT8_MIN) { @@ -610,7 +612,7 @@ static void audio_filter_amp (aos_t *this, void *buf, int num_frames) { int32_t test; int16_t *mem = (int16_t *) buf; - for (i=0; i<num_frames*num_channels; i++) { + for (i=0; i<total_frames; i++) { test = mem[i] * amp_factor; /* Force limit on amp_factor to prevent clipping */ if (test < INT16_MIN) { diff --git a/src/xine-engine/audio_out.h b/src/xine-engine/audio_out.h index c4581ec24..6ead6505e 100644 --- a/src/xine-engine/audio_out.h +++ b/src/xine-engine/audio_out.h @@ -255,11 +255,12 @@ struct audio_driver_class_s { void (*dispose) (audio_driver_class_t *); }; -/* - * this initiates the audio_out sync routines - * found in ./src/xine-engine/audio_out.c +/** + * @brief Initialise the audio_out sync routines + * + * @internal */ -xine_audio_port_t *_x_ao_new_port (xine_t *xine, ao_driver_t *driver, int grab_only) XINE_PROTECTED; +xine_audio_port_t *_x_ao_new_port (xine_t *xine, ao_driver_t *driver, int grab_only); /* * audio output modes + capabilities diff --git a/src/xine-engine/buffer.h b/src/xine-engine/buffer.h index b08960e7d..20579f12d 100644 --- a/src/xine-engine/buffer.h +++ b/src/xine-engine/buffer.h @@ -53,8 +53,8 @@ extern "C" { #define BUF_MAX_CALLBACKS 5 -/* - * buffer types +/** + * @defgroup buffer_types Buffer Types * * a buffer type ID describes the contents of a buffer * it consists of three fields: @@ -65,17 +65,20 @@ extern "C" { * DD : decoder selection (e.g. MPEG, OPENDIVX ... for VIDEO) * CCCC : channel number or other subtype information for the decoder */ +/*@{*/ #define BUF_MAJOR_MASK 0xFF000000 #define BUF_DECODER_MASK 0x00FF0000 -/* control buffer types */ - +/** + * @defgroup buffer_ctrl Control buffer types + */ +/*@{*/ #define BUF_CONTROL_BASE 0x01000000 #define BUF_CONTROL_START 0x01000000 #define BUF_CONTROL_END 0x01010000 #define BUF_CONTROL_QUIT 0x01020000 -#define BUF_CONTROL_DISCONTINUITY 0x01030000 /* former AVSYNC_RESET */ +#define BUF_CONTROL_DISCONTINUITY 0x01030000 /**< former AVSYNC_RESET */ #define BUF_CONTROL_NOP 0x01040000 #define BUF_CONTROL_AUDIO_CHANNEL 0x01050000 #define BUF_CONTROL_SPU_CHANNEL 0x01060000 @@ -84,11 +87,15 @@ extern "C" { #define BUF_CONTROL_HEADERS_DONE 0x01090000 #define BUF_CONTROL_FLUSH_DECODER 0x010a0000 #define BUF_CONTROL_RESET_TRACK_MAP 0x010b0000 +/*@}*/ -/* video buffer types: (please keep in sync with buffer_types.c) */ - +/** + * @defgroup buffer_video Video buffer types + * @note (please keep in sync with buffer_types.c) + */ +/*@{*/ #define BUF_VIDEO_BASE 0x02000000 -#define BUF_VIDEO_UNKNOWN 0x02ff0000 /* no decoder should handle this one */ +#define BUF_VIDEO_UNKNOWN 0x02ff0000 /**< no decoder should handle this one */ #define BUF_VIDEO_MPEG 0x02000000 #define BUF_VIDEO_MPEG4 0x02010000 #define BUF_VIDEO_CINEPAK 0x02020000 @@ -147,7 +154,7 @@ extern "C" { #define BUF_VIDEO_INTERPLAY 0x02380000 #define BUF_VIDEO_RV40 0x02390000 #define BUF_VIDEO_PSX_MDEC 0x023A0000 -#define BUF_VIDEO_YUV_FRAMES 0x023B0000 /* uncompressed YUV, delivered by v4l input plugin */ +#define BUF_VIDEO_YUV_FRAMES 0x023B0000 /**< uncompressed YUV, delivered by v4l input plugin */ #define BUF_VIDEO_HUFFYUV 0x023C0000 #define BUF_VIDEO_IMAGE 0x023D0000 #define BUF_VIDEO_THEORA 0x023E0000 @@ -162,8 +169,8 @@ extern "C" { #define BUF_VIDEO_8BPS 0x02470000 #define BUF_VIDEO_ASV1 0x02480000 #define BUF_VIDEO_ASV2 0x02490000 -#define BUF_VIDEO_BITPLANE 0x024A0000 /* Amiga typical picture and animation format */ -#define BUF_VIDEO_BITPLANE_BR1 0x024B0000 /* the same with Bytrun compression 1 */ +#define BUF_VIDEO_BITPLANE 0x024A0000 /**< Amiga typical picture and animation format */ +#define BUF_VIDEO_BITPLANE_BR1 0x024B0000 /**< the same with Bytrun compression 1 */ #define BUF_VIDEO_FLV1 0x024C0000 #define BUF_VIDEO_H264 0x024D0000 #define BUF_VIDEO_MJPEG_B 0x024E0000 @@ -189,11 +196,15 @@ extern "C" { #define BUF_VIDEO_CAVS 0x02620000 #define BUF_VIDEO_VP6F 0x02630000 #define BUF_VIDEO_THEORA_RAW 0x02640000 +/*@}*/ -/* audio buffer types: (please keep in sync with buffer_types.c) */ - +/** + * @defgroup buffer_audio Audio buffer types + * @note (please keep in sync with buffer_types.c) + */ +/*@{*/ #define BUF_AUDIO_BASE 0x03000000 -#define BUF_AUDIO_UNKNOWN 0x03ff0000 /* no decoder should handle this one */ +#define BUF_AUDIO_UNKNOWN 0x03ff0000 /**< no decoder should handle this one */ #define BUF_AUDIO_A52 0x03000000 #define BUF_AUDIO_MPEG 0x03010000 #define BUF_AUDIO_LPCM_BE 0x03020000 @@ -256,9 +267,12 @@ extern "C" { #define BUF_AUDIO_SMACKER 0x033B0000 #define BUF_AUDIO_FLVADPCM 0x033C0000 #define BUF_AUDIO_WAVPACK 0x033D0000 +/*@}*/ -/* spu buffer types: */ - +/** + * @defgroup buffer_spu SPU buffer types + */ +/*@{*/ #define BUF_SPU_BASE 0x04000000 #define BUF_SPU_DVD 0x04000000 #define BUF_SPU_TEXT 0x04010000 @@ -268,33 +282,41 @@ extern "C" { #define BUF_SPU_CVD 0x04050000 #define BUF_SPU_OGM 0x04060000 #define BUF_SPU_CMML 0x04070000 +/*@}*/ -/* demuxer block types: */ - +/** + * @defgroup buffer_demux Demuxer block types + */ +/*@{*/ #define BUF_DEMUX_BLOCK 0x05000000 +/*@}*/ + +/*@}*/ typedef struct extra_info_s extra_info_t; -/* - * extra_info_t is used to pass information from input or demuxer plugins - * to output frames (past decoder). new data must be added after the existing - * fields for backward compatibility. +/** + * @brief Structure to pass information from input or demuxer plugins + * to output frames (past decoder). + * + * New data must be added after the existing fields to not break ABI + * (backward compatibility). */ struct extra_info_s { - int input_normpos; /* remember where this buf came from in - * the input source (0..65535). can be - * either time or offset based. */ - int input_time; /* time offset in miliseconds from - * beginning of stream */ - uint32_t frame_number; /* number of current frame if known */ + int input_normpos; /**< remember where this buf came from in + * the input source (0..65535). can be + * either time or offset based. */ + int input_time; /**< time offset in miliseconds from + * beginning of stream */ + uint32_t frame_number; /**< number of current frame if known */ - int seek_count; /* internal engine use */ - int64_t vpts; /* set on output layers only */ + int seek_count; /**< internal engine use */ + int64_t vpts; /**< set on output layers only */ - int invalid; /* do not use this extra info to update anything */ - int total_time; /* duration in miliseconds of the stream */ + int invalid; /**< do not use this extra info to update anything */ + int total_time; /**< duration in miliseconds of the stream */ }; @@ -305,74 +327,75 @@ struct buf_element_s { buf_element_t *next; unsigned char *mem; - unsigned char *content; /* start of raw content in mem (without header etc) */ + unsigned char *content; /**< start of raw content in mem (without header etc) */ - int32_t size ; /* size of _content_ */ - int32_t max_size; /* size of pre-allocated memory pointed to by "mem" */ - uint32_t type; - int64_t pts; /* presentation time stamp, used for a/v sync */ - int64_t disc_off; /* discontinuity offset */ + int32_t size ; /**< size of _content_ */ + int32_t max_size; /**< size of pre-allocated memory pointed to by "mem" */ + int64_t pts; /**< presentation time stamp, used for a/v sync */ + int64_t disc_off; /**< discontinuity offset */ - extra_info_t *extra_info; /* extra info will be passed to frames */ + extra_info_t *extra_info; /**< extra info will be passed to frames */ - uint32_t decoder_flags; /* stuff like keyframe, is_header ... see below */ + uint32_t decoder_flags; /**< stuff like keyframe, is_header ... see below */ - /* additional decoder flags and other dec-spec. stuff */ + /** additional decoder flags and other dec-spec. stuff */ uint32_t decoder_info[BUF_NUM_DEC_INFO]; - /* pointers to dec-spec. stuff */ + /** pointers to dec-spec. stuff */ void *decoder_info_ptr[BUF_NUM_DEC_INFO]; void (*free_buffer) (buf_element_t *buf); - void *source; /* pointer to source of this buffer for */ - /* free_buffer */ + void *source; /**< pointer to source of this buffer for + * free_buffer */ + uint32_t type; } ; -/* keyframe should be set whenever possible (that is, when demuxer +/** keyframe should be set whenever possible (that is, when demuxer * knows about frames and keyframes). */ #define BUF_FLAG_KEYFRAME 0x0001 -/* frame start/end. BUF_FLAG_FRAME_END is sent on last buf of a frame */ +/** frame start/end. BUF_FLAG_FRAME_END is sent on last buf of a frame */ #define BUF_FLAG_FRAME_START 0x0002 #define BUF_FLAG_FRAME_END 0x0004 -/* any out-of-band data needed to initialize decoder must have +/** any out-of-band data needed to initialize decoder must have * this flag set. */ #define BUF_FLAG_HEADER 0x0008 -/* preview buffers are normal data buffers that must not produce any +/** preview buffers are normal data buffers that must not produce any * output in decoders (may be used to sneak details about the stream * to come). */ #define BUF_FLAG_PREVIEW 0x0010 -/* set when user stop the playback */ +/** set when user stop the playback */ #define BUF_FLAG_END_USER 0x0020 -/* set when stream finished naturaly */ +/** set when stream finished naturaly */ #define BUF_FLAG_END_STREAM 0x0040 -/* decoder_info[0] carries the frame step (1/90000). */ +/** decoder_info[0] carries the frame step (1/90000). */ #define BUF_FLAG_FRAMERATE 0x0080 -/* hint to metronom that seeking has occurred */ +/** hint to metronom that seeking has occurred */ #define BUF_FLAG_SEEK 0x0100 -/* special information inside, see below. */ +/** special information inside, see below. */ #define BUF_FLAG_SPECIAL 0x0200 -/* header use standard xine_bmiheader or xine_waveformatex structs. +/** header use standard xine_bmiheader or xine_waveformatex structs. * xine_waveformatex is actually optional since the most important * information for audio init is available from decoder_info[]. * note: BUF_FLAG_HEADER must also be set. */ #define BUF_FLAG_STDHEADER 0x0400 -/* decoder_info[1] carries numerator for display aspect ratio +/** decoder_info[1] carries numerator for display aspect ratio * decoder_info[2] carries denominator for display aspect ratio */ #define BUF_FLAG_ASPECT 0x0800 -/* Special buffer types: +/** + * \defgroup buffer_special Special buffer types: * Sometimes there is a need to relay special information from a demuxer * to a video decoder. For example, some file types store palette data in * the file header independant of the video data. The special buffer type @@ -391,10 +414,9 @@ struct buf_element_s { * buffer will fall through to the case where the buffer's data content * is accumulated and no harm will be done. */ +/*@{*/ -/* these are the types of special buffers */ - -/* +/** * In a BUF_SPECIAL_PALETTE buffer: * decoder_info[1] = BUF_SPECIAL_PALETTE * decoder_info[2] = number of entries in palette table @@ -412,7 +434,7 @@ struct buf_element_s { /* special buffer type 2 used to be defined but is now available for use */ -/* +/** * In a BUF_SPECIAL_ASPECT buffer: * decoder_info[1] = BUF_SPECIAL_ASPECT * decoder_info[2] = MPEG2 aspect ratio code @@ -425,7 +447,7 @@ struct buf_element_s { */ #define BUF_SPECIAL_ASPECT 3 -/* +/** * In a BUF_SPECIAL_DECODER_CONFIG buffer: * decoder_info[1] = BUF_SPECIAL_DECODER_CONFIG * decoder_info[2] = data size @@ -435,7 +457,7 @@ struct buf_element_s { */ #define BUF_SPECIAL_DECODER_CONFIG 4 -/* +/** * In a BUF_SPECIAL_STSD_ATOM buffer: * decoder_info[1] = BUF_SPECIAL_STSD_ATOM * decoder_info[2] = size of the ImageDescription atom, minus the @@ -449,7 +471,7 @@ struct buf_element_s { */ #define BUF_SPECIAL_STSD_ATOM 5 -/* +/** * In a BUF_SPECIAL_LPCM_CONFIG buffer: * decoder_info[1] = BUF_SPECIAL_LPCM_CONFIG * decoder_info[2] = config data @@ -459,7 +481,7 @@ struct buf_element_s { */ #define BUF_SPECIAL_LPCM_CONFIG 6 -/* +/** * In a BUF_SPECIAL_CHARSET_ENCODING buffer: * decoder_info[1] = BUF_SPECIAL_CHARSET_ENCODING * decoder_info[2] = size of charset encoding string @@ -471,7 +493,7 @@ struct buf_element_s { #define BUF_SPECIAL_CHARSET_ENCODING 7 -/* +/** * In a BUF_SPECIAL_SPU_DVD_SUBTYPE: * decoder_info[1] = BUF_SPECIAL_SPU_DVD_SUBTYPE * decoder_info[2] = subtype @@ -486,7 +508,8 @@ struct buf_element_s { #define SPU_DVD_SUBTYPE_VOBSUB_PACKAGE 3 #define SPU_DVD_SUBTYPE_NAV 4 -/* In a BUF_SPECIAL_SPU_DVB_DESCRIPTOR +/** + * In a BUF_SPECIAL_SPU_DVB_DESCRIPTOR * decoder_info[1] = BUF_SPECIAL_SPU_DVB_DESCRIPTOR * decoder_info[2] = size of spu_dvb_descriptor_t * decoder_info_ptr[2] = pointer to spu_dvb_descriptor_t, or NULL @@ -498,7 +521,7 @@ struct buf_element_s { **/ #define BUF_SPECIAL_SPU_DVB_DESCRIPTOR 9 -/* +/** * In a BUF_SPECIAL_RV_CHUNK_TABLE: * decoder_info[1] = BUF_SPECIAL_RV_CHUNK_TABLE * decoder_info[2] = number of entries in chunk table @@ -507,6 +530,7 @@ struct buf_element_s { * This buffer transports the chunk table associated to each RealVideo frame. */ #define BUF_SPECIAL_RV_CHUNK_TABLE 10 +/*@}*/ typedef struct spu_dvb_descriptor_s spu_dvb_descriptor_t; struct spu_dvb_descriptor_s @@ -598,42 +622,61 @@ struct fifo_buffer_s void *get_cb_data[BUF_MAX_CALLBACKS]; } ; -/* - * allocate and initialize new (empty) fifo buffer, - * init buffer pool for it: - * allocate num_buffers of buf_size bytes each +/** + * @brief Allocate and initialise new (empty) FIFO buffers. + * @param num_buffer Number of buffers to allocate. + * @param buf_size Size of each buffer. + * @internal Only used by video and audio decoder loops. */ +fifo_buffer_t *_x_fifo_buffer_new (int num_buffers, uint32_t buf_size); -fifo_buffer_t *_x_fifo_buffer_new (int num_buffers, uint32_t buf_size) XINE_PROTECTED; -fifo_buffer_t *_x_dummy_fifo_buffer_new (int num_buffers, uint32_t buf_size) XINE_PROTECTED; +/** + * @brief Allocate and initialise new dummy FIFO buffers. + * @param num_buffer Number of dummy buffers to allocate. + * @param buf_size Size of each buffer. + * @internal Only used by video and audio decoder loops. + */ +fifo_buffer_t *_x_dummy_fifo_buffer_new (int num_buffers, uint32_t buf_size); -/* return BUF_VIDEO_xxx given the fourcc - * fourcc_int must be read in machine endianness +/** + * @brief Returns the \ref buffer_video "BUF_VIDEO_xxx" for the given fourcc. + * @param fourcc_int 32-bit FOURCC value in machine endianness + * @sa _x_formattag_to_buf_audio + * * example: fourcc_int = *(uint32_t *)fourcc_char; */ uint32_t _x_fourcc_to_buf_video( uint32_t fourcc_int ) XINE_PROTECTED; -/* return codec name given BUF_VIDEO_xxx */ -char * _x_buf_video_name( uint32_t buf_type ) XINE_PROTECTED; +/** + * @brief Returns video codec name given the buffer type. + * @param buf_type One of the \ref buffer_video "BUF_VIDEO_xxx" values. + * @sa _x_buf_audio_name + */ +const char *_x_buf_video_name( uint32_t buf_type ) XINE_PROTECTED; -/* return BUF_AUDIO_xxx given the formattag */ +/** + * @brief Returns the \ref buffer_audio "BUF_AUDIO_xxx" for the given formattag. + * @param formattagg 32-bit format tag value in machine endianness + * @sa _x_fourcc_to_buf_video + */ uint32_t _x_formattag_to_buf_audio( uint32_t formattag ) XINE_PROTECTED; -/* return codec name given BUF_AUDIO_xxx */ -char * _x_buf_audio_name( uint32_t buf_type ) XINE_PROTECTED; +/** + * @brief Returns audio codec name given the buffer type. + * @param buf_type One of the \ref buffer_audio "BUF_AUDIO_xxx" values. + * @sa _x_buf_video_name + */ +const char *_x_buf_audio_name( uint32_t buf_type ) XINE_PROTECTED; -#ifndef ATTRIBUTE_PACKED -/* no attribute packed? let's try with pragma pack as a last resort */ -#pragma pack(2) -#endif -/* this is xine version of BITMAPINFOHEADER - * - should be safe to compile on 64bits machines - * - will always use machine endian format, so demuxers reading - * stuff from win32 formats must use the function below. +/** + * @brief xine version of BITMAPINFOHEADER. + * @note Should be safe to compile on 64bits machines. + * @note Will always use machine endian format, so demuxers reading + * stuff from win32 formats must use the function below. */ -typedef struct __attribute__((__packed__)) { +typedef struct XINE_PACKED { int32_t biSize; int32_t biWidth; int32_t biHeight; @@ -647,10 +690,11 @@ typedef struct __attribute__((__packed__)) { int32_t biClrImportant; } xine_bmiheader; -/* this is xine version of WAVEFORMATEX - * (the same comments from xine_bmiheader) +/** + * @brief xine version of WAVEFORMATEX. + * @note The same comments from xine_bmiheader applies. */ -typedef struct __attribute__((__packed__)) { +typedef struct XINE_PACKED { int16_t wFormatTag; int16_t nChannels; int32_t nSamplesPerSec; @@ -659,14 +703,11 @@ typedef struct __attribute__((__packed__)) { int16_t wBitsPerSample; int16_t cbSize; } xine_waveformatex; -#ifndef ATTRIBUTE_PACKED -#pragma pack() -#endif -/* convert xine_bmiheader struct from little endian */ +/** Convert xine_bmiheader struct from little endian */ void _x_bmiheader_le2me( xine_bmiheader *bih ) XINE_PROTECTED; -/* convert xine_waveformatex struct from little endian */ +/** Convert xine_waveformatex struct from little endian */ void _x_waveformatex_le2me( xine_waveformatex *wavex ) XINE_PROTECTED; #ifdef __cplusplus diff --git a/src/xine-engine/buffer_types.c b/src/xine-engine/buffer_types.c index 9ce7956c9..95a9f40ac 100644 --- a/src/xine-engine/buffer_types.c +++ b/src/xine-engine/buffer_types.c @@ -35,14 +35,6 @@ #include "buffer.h" #include "bswap.h" -/* FOURCC will be manipulated using machine endian */ -#ifdef WORDS_BIGENDIAN -#define meFOURCC BE_FOURCC -#else -#define meFOURCC LE_FOURCC -#endif - - typedef struct video_db_s { uint32_t fourcc[20]; uint32_t buf_type; @@ -59,12 +51,12 @@ typedef struct audio_db_s { static const video_db_t video_db[] = { { { - meFOURCC('m', 'p', 'e', 'g'), - meFOURCC('M', 'P', 'E', 'G'), - meFOURCC('P', 'I', 'M', '1'), - meFOURCC('m', 'p', 'g', '2'), - meFOURCC('m', 'p', 'g', '1'), - meFOURCC(0x02, 0, 0, 0x10), + ME_FOURCC('m', 'p', 'e', 'g'), + ME_FOURCC('M', 'P', 'E', 'G'), + ME_FOURCC('P', 'I', 'M', '1'), + ME_FOURCC('m', 'p', 'g', '2'), + ME_FOURCC('m', 'p', 'g', '1'), + ME_FOURCC(0x02, 0, 0, 0x10), 0 }, BUF_VIDEO_MPEG, @@ -72,15 +64,15 @@ static const video_db_t video_db[] = { }, { { - meFOURCC('D', 'I', 'V', 'X'), - meFOURCC('d', 'i', 'v', 'x'), - meFOURCC('D', 'i', 'v', 'x'), - meFOURCC('D', 'i', 'v', 'X'), - meFOURCC('M', 'P', '4', 'S'), - meFOURCC('m', 'p', '4', 'v'), - meFOURCC('M', '4', 'S', '2'), - meFOURCC('m', '4', 's', '2'), - meFOURCC('F', 'M', 'P', '4'), + ME_FOURCC('D', 'I', 'V', 'X'), + ME_FOURCC('d', 'i', 'v', 'x'), + ME_FOURCC('D', 'i', 'v', 'x'), + ME_FOURCC('D', 'i', 'v', 'X'), + ME_FOURCC('M', 'P', '4', 'S'), + ME_FOURCC('m', 'p', '4', 'v'), + ME_FOURCC('M', '4', 'S', '2'), + ME_FOURCC('m', '4', 's', '2'), + ME_FOURCC('F', 'M', 'P', '4'), 0 }, BUF_VIDEO_MPEG4, @@ -88,8 +80,8 @@ static const video_db_t video_db[] = { }, { { - meFOURCC('X', 'V', 'I', 'D'), - meFOURCC('x', 'v', 'i', 'd'), + ME_FOURCC('X', 'V', 'I', 'D'), + ME_FOURCC('x', 'v', 'i', 'd'), 0 }, BUF_VIDEO_XVID, @@ -97,7 +89,7 @@ static const video_db_t video_db[] = { }, { { - meFOURCC('D', 'X', '5', '0'), + ME_FOURCC('D', 'X', '5', '0'), 0 }, BUF_VIDEO_DIVX5, @@ -105,7 +97,7 @@ static const video_db_t video_db[] = { }, { { - meFOURCC('c', 'v', 'i', 'd'), + ME_FOURCC('c', 'v', 'i', 'd'), 0 }, BUF_VIDEO_CINEPAK, @@ -113,9 +105,9 @@ static const video_db_t video_db[] = { }, { { - meFOURCC('S', 'V', 'Q', '1'), - meFOURCC('s', 'v', 'q', '1'), - meFOURCC('s', 'v', 'q', 'i'), + ME_FOURCC('S', 'V', 'Q', '1'), + ME_FOURCC('s', 'v', 'q', '1'), + ME_FOURCC('s', 'v', 'q', 'i'), 0 }, BUF_VIDEO_SORENSON_V1, @@ -123,8 +115,8 @@ static const video_db_t video_db[] = { }, { { - meFOURCC('S', 'V', 'Q', '3'), - meFOURCC('s', 'v', 'q', '3'), + ME_FOURCC('S', 'V', 'Q', '3'), + ME_FOURCC('s', 'v', 'q', '3'), 0 }, BUF_VIDEO_SORENSON_V3, @@ -132,10 +124,10 @@ static const video_db_t video_db[] = { }, { { - meFOURCC('M', 'P', '4', '1'), - meFOURCC('m', 'p', '4', '1'), - meFOURCC('M', 'P', 'G', '4'), - meFOURCC('m', 'p', 'g', '4'), + ME_FOURCC('M', 'P', '4', '1'), + ME_FOURCC('m', 'p', '4', '1'), + ME_FOURCC('M', 'P', 'G', '4'), + ME_FOURCC('m', 'p', 'g', '4'), 0 }, BUF_VIDEO_MSMPEG4_V1, @@ -143,12 +135,12 @@ static const video_db_t video_db[] = { }, { { - meFOURCC('M', 'P', '4', '1'), - meFOURCC('m', 'p', '4', '1'), - meFOURCC('M', 'P', '4', '2'), - meFOURCC('m', 'p', '4', '2'), - meFOURCC('D', 'I', 'V', '2'), - meFOURCC('d', 'i', 'v', '2'), + ME_FOURCC('M', 'P', '4', '1'), + ME_FOURCC('m', 'p', '4', '1'), + ME_FOURCC('M', 'P', '4', '2'), + ME_FOURCC('m', 'p', '4', '2'), + ME_FOURCC('D', 'I', 'V', '2'), + ME_FOURCC('d', 'i', 'v', '2'), 0 }, BUF_VIDEO_MSMPEG4_V2, @@ -156,20 +148,20 @@ static const video_db_t video_db[] = { }, { { - meFOURCC('M', 'P', '4', '3'), - meFOURCC('m', 'p', '4', '3'), - meFOURCC('D', 'I', 'V', '3'), - meFOURCC('d', 'i', 'v', '3'), - meFOURCC('D', 'I', 'V', '4'), - meFOURCC('d', 'i', 'v', '4'), - meFOURCC('D', 'I', 'V', '5'), - meFOURCC('d', 'i', 'v', '5'), - meFOURCC('D', 'I', 'V', '6'), - meFOURCC('d', 'i', 'v', '6'), - meFOURCC('A', 'P', '4', '1'), - meFOURCC('M', 'P', 'G', '3'), - meFOURCC('C', 'O', 'L', '1'), - meFOURCC('3', 'I', 'V', 'D'), + ME_FOURCC('M', 'P', '4', '3'), + ME_FOURCC('m', 'p', '4', '3'), + ME_FOURCC('D', 'I', 'V', '3'), + ME_FOURCC('d', 'i', 'v', '3'), + ME_FOURCC('D', 'I', 'V', '4'), + ME_FOURCC('d', 'i', 'v', '4'), + ME_FOURCC('D', 'I', 'V', '5'), + ME_FOURCC('d', 'i', 'v', '5'), + ME_FOURCC('D', 'I', 'V', '6'), + ME_FOURCC('d', 'i', 'v', '6'), + ME_FOURCC('A', 'P', '4', '1'), + ME_FOURCC('M', 'P', 'G', '3'), + ME_FOURCC('C', 'O', 'L', '1'), + ME_FOURCC('3', 'I', 'V', 'D'), 0 }, BUF_VIDEO_MSMPEG4_V3, @@ -177,8 +169,8 @@ static const video_db_t video_db[] = { }, { { - meFOURCC('3', 'I', 'V', '1'), - meFOURCC('3', 'I', 'V', '2'), + ME_FOURCC('3', 'I', 'V', '1'), + ME_FOURCC('3', 'I', 'V', '2'), 0 }, BUF_VIDEO_3IVX, @@ -186,11 +178,11 @@ static const video_db_t video_db[] = { }, { { - meFOURCC('d', 'm', 'b', '1'), - meFOURCC('M', 'J', 'P', 'G'), - meFOURCC('m', 'j', 'p', 'a'), - meFOURCC('A', 'V', 'R', 'n'), - meFOURCC('A', 'V', 'D', 'J'), + ME_FOURCC('d', 'm', 'b', '1'), + ME_FOURCC('M', 'J', 'P', 'G'), + ME_FOURCC('m', 'j', 'p', 'a'), + ME_FOURCC('A', 'V', 'R', 'n'), + ME_FOURCC('A', 'V', 'D', 'J'), 0 }, BUF_VIDEO_MJPEG, @@ -198,7 +190,7 @@ static const video_db_t video_db[] = { }, { { - meFOURCC('m', 'j', 'p', 'b'), + ME_FOURCC('m', 'j', 'p', 'b'), 0 }, BUF_VIDEO_MJPEG_B, @@ -206,8 +198,8 @@ static const video_db_t video_db[] = { }, { { - meFOURCC('I', 'V', '5', '0'), - meFOURCC('i', 'v', '5', '0'), + ME_FOURCC('I', 'V', '5', '0'), + ME_FOURCC('i', 'v', '5', '0'), 0 }, BUF_VIDEO_IV50, @@ -215,8 +207,8 @@ static const video_db_t video_db[] = { }, { { - meFOURCC('I', 'V', '4', '1'), - meFOURCC('i', 'v', '4', '1'), + ME_FOURCC('I', 'V', '4', '1'), + ME_FOURCC('i', 'v', '4', '1'), 0 }, BUF_VIDEO_IV41, @@ -224,8 +216,8 @@ static const video_db_t video_db[] = { }, { { - meFOURCC('I', 'V', '3', '2'), - meFOURCC('i', 'v', '3', '2'), + ME_FOURCC('I', 'V', '3', '2'), + ME_FOURCC('i', 'v', '3', '2'), 0 }, BUF_VIDEO_IV32, @@ -233,8 +225,8 @@ static const video_db_t video_db[] = { }, { { - meFOURCC('I', 'V', '3', '1'), - meFOURCC('i', 'v', '3', '1'), + ME_FOURCC('I', 'V', '3', '1'), + ME_FOURCC('i', 'v', '3', '1'), 0 }, BUF_VIDEO_IV31, @@ -242,7 +234,7 @@ static const video_db_t video_db[] = { }, { { - meFOURCC('V', 'C', 'R', '1'), + ME_FOURCC('V', 'C', 'R', '1'), 0 }, BUF_VIDEO_ATIVCR1, @@ -250,7 +242,7 @@ static const video_db_t video_db[] = { }, { { - meFOURCC('V', 'C', 'R', '2'), + ME_FOURCC('V', 'C', 'R', '2'), 0 }, BUF_VIDEO_ATIVCR2, @@ -258,11 +250,11 @@ static const video_db_t video_db[] = { }, { { - meFOURCC('I', '2', '6', '3'), - meFOURCC('i', '2', '6', '3'), - meFOURCC('V', 'I', 'V', 'O'), - meFOURCC('v', 'i', 'v', 'o'), - meFOURCC('v', 'i', 'v', '1'), + ME_FOURCC('I', '2', '6', '3'), + ME_FOURCC('i', '2', '6', '3'), + ME_FOURCC('V', 'I', 'V', 'O'), + ME_FOURCC('v', 'i', 'v', 'o'), + ME_FOURCC('v', 'i', 'v', '1'), 0 }, BUF_VIDEO_I263, @@ -270,8 +262,8 @@ static const video_db_t video_db[] = { }, { { - meFOURCC('D','I','B',' '), /* device-independent bitmap */ - meFOURCC('r','a','w',' '), + ME_FOURCC('D','I','B',' '), /* device-independent bitmap */ + ME_FOURCC('r','a','w',' '), 0 }, BUF_VIDEO_RGB, @@ -283,8 +275,8 @@ static const video_db_t video_db[] = { else if (!strncasecmp (video, "yuv2", 4)) this->video_type = BUF_VIDEO_YUY2; */ - meFOURCC('y', 'u', 'v', '2'), - meFOURCC('Y', 'U', 'Y', '2'), + ME_FOURCC('y', 'u', 'v', '2'), + ME_FOURCC('Y', 'U', 'Y', '2'), 0 }, BUF_VIDEO_YUY2, @@ -292,8 +284,8 @@ static const video_db_t video_db[] = { }, { { - meFOURCC('j','p','e','g'), - meFOURCC('J','F','I','F'), + ME_FOURCC('j','p','e','g'), + ME_FOURCC('J','F','I','F'), 0 }, BUF_VIDEO_JPEG, @@ -301,7 +293,7 @@ static const video_db_t video_db[] = { }, { { - meFOURCC('W','M','V','1'), + ME_FOURCC('W','M','V','1'), 0 }, BUF_VIDEO_WMV7, @@ -309,7 +301,7 @@ static const video_db_t video_db[] = { }, { { - meFOURCC('W','M','V','2'), + ME_FOURCC('W','M','V','2'), 0 }, BUF_VIDEO_WMV8, @@ -317,8 +309,8 @@ static const video_db_t video_db[] = { }, { { - meFOURCC('W','M','V','3'), - meFOURCC('W','M','V','P'), + ME_FOURCC('W','M','V','3'), + ME_FOURCC('W','M','V','P'), 0 }, BUF_VIDEO_WMV9, @@ -326,12 +318,12 @@ static const video_db_t video_db[] = { }, { { - meFOURCC('c','r','a','m'), - meFOURCC('C','R','A','M'), - meFOURCC('M','S','V','C'), - meFOURCC('m','s','v','c'), - meFOURCC('W','H','A','M'), - meFOURCC('w','h','a','m'), + ME_FOURCC('c','r','a','m'), + ME_FOURCC('C','R','A','M'), + ME_FOURCC('M','S','V','C'), + ME_FOURCC('m','s','v','c'), + ME_FOURCC('W','H','A','M'), + ME_FOURCC('w','h','a','m'), 0 }, BUF_VIDEO_MSVC, @@ -339,9 +331,9 @@ static const video_db_t video_db[] = { }, { { - meFOURCC('D','V','S','D'), - meFOURCC('d','v','s','d'), - meFOURCC('d','v','c','p'), + ME_FOURCC('D','V','S','D'), + ME_FOURCC('d','v','s','d'), + ME_FOURCC('d','v','c','p'), 0 }, BUF_VIDEO_DV, @@ -349,11 +341,11 @@ static const video_db_t video_db[] = { }, { { - meFOURCC('V','P','3',' '), - meFOURCC('V','P','3','0'), - meFOURCC('v','p','3','0'), - meFOURCC('V','P','3','1'), - meFOURCC('v','p','3','1'), + ME_FOURCC('V','P','3',' '), + ME_FOURCC('V','P','3','0'), + ME_FOURCC('v','p','3','0'), + ME_FOURCC('V','P','3','1'), + ME_FOURCC('v','p','3','1'), 0 }, BUF_VIDEO_VP31, @@ -361,7 +353,7 @@ static const video_db_t video_db[] = { }, { { - meFOURCC('V','P','4','0'), + ME_FOURCC('V','P','4','0'), 0, }, BUF_VIDEO_VP4, @@ -369,10 +361,10 @@ static const video_db_t video_db[] = { }, { { - meFOURCC('H', '2', '6', '3'), - meFOURCC('h', '2', '6', '3'), - meFOURCC('U', '2', '6', '3'), - meFOURCC('s', '2', '6', '3'), + ME_FOURCC('H', '2', '6', '3'), + ME_FOURCC('h', '2', '6', '3'), + ME_FOURCC('U', '2', '6', '3'), + ME_FOURCC('s', '2', '6', '3'), 0 }, BUF_VIDEO_H263, @@ -380,8 +372,8 @@ static const video_db_t video_db[] = { }, { { - meFOURCC('c', 'y', 'u', 'v'), - meFOURCC('C', 'Y', 'U', 'V'), + ME_FOURCC('c', 'y', 'u', 'v'), + ME_FOURCC('C', 'Y', 'U', 'V'), 0 }, BUF_VIDEO_CYUV, @@ -389,7 +381,7 @@ static const video_db_t video_db[] = { }, { { - meFOURCC('s', 'm', 'c', ' '), + ME_FOURCC('s', 'm', 'c', ' '), 0 }, BUF_VIDEO_SMC, @@ -397,8 +389,8 @@ static const video_db_t video_db[] = { }, { { - meFOURCC('r', 'p', 'z', 'a'), - meFOURCC('a', 'z', 'p', 'r'), + ME_FOURCC('r', 'p', 'z', 'a'), + ME_FOURCC('a', 'z', 'p', 'r'), 0 }, BUF_VIDEO_RPZA, @@ -406,7 +398,7 @@ static const video_db_t video_db[] = { }, { { - meFOURCC('r', 'l', 'e', ' '), + ME_FOURCC('r', 'l', 'e', ' '), 0 }, BUF_VIDEO_QTRLE, @@ -421,7 +413,7 @@ static const video_db_t video_db[] = { }, { { - meFOURCC('D', 'U', 'C', 'K'), + ME_FOURCC('D', 'U', 'C', 'K'), 0 }, BUF_VIDEO_DUCKTM1, @@ -429,7 +421,7 @@ static const video_db_t video_db[] = { }, { { - meFOURCC('M', 'S', 'S', '1'), + ME_FOURCC('M', 'S', 'S', '1'), 0 }, BUF_VIDEO_MSS1, @@ -437,7 +429,7 @@ static const video_db_t video_db[] = { }, { { - meFOURCC('P', 'G', 'V', 'V'), + ME_FOURCC('P', 'G', 'V', 'V'), 0 }, BUF_VIDEO_PGVV, @@ -445,7 +437,7 @@ static const video_db_t video_db[] = { }, { { - meFOURCC('Z', 'y', 'G', 'o'), + ME_FOURCC('Z', 'y', 'G', 'o'), 0 }, BUF_VIDEO_ZYGO, @@ -453,7 +445,7 @@ static const video_db_t video_db[] = { }, { { - meFOURCC('t', 's', 'c', 'c'), + ME_FOURCC('t', 's', 'c', 'c'), 0 }, BUF_VIDEO_TSCC, @@ -461,7 +453,7 @@ static const video_db_t video_db[] = { }, { { - meFOURCC('Y', 'V', 'U', '9'), + ME_FOURCC('Y', 'V', 'U', '9'), 0 }, BUF_VIDEO_YVU9, @@ -469,7 +461,7 @@ static const video_db_t video_db[] = { }, { { - meFOURCC('G', 'R', 'E', 'Y'), + ME_FOURCC('G', 'R', 'E', 'Y'), 0 }, BUF_VIDEO_GREY, @@ -477,9 +469,9 @@ static const video_db_t video_db[] = { }, { { - meFOURCC('X', 'x', 'a', 'n'), - meFOURCC('X', 'X', 'A', 'N'), - meFOURCC('x', 'x', 'a', 'n'), + ME_FOURCC('X', 'x', 'a', 'n'), + ME_FOURCC('X', 'X', 'A', 'N'), + ME_FOURCC('x', 'x', 'a', 'n'), 0 }, BUF_VIDEO_XXAN, @@ -487,8 +479,8 @@ static const video_db_t video_db[] = { }, { { - meFOURCC('Y', 'V', '1', '2'), - meFOURCC('y', 'v', '1', '2'), + ME_FOURCC('Y', 'V', '1', '2'), + ME_FOURCC('y', 'v', '1', '2'), 0 }, BUF_VIDEO_YV12, @@ -496,8 +488,8 @@ static const video_db_t video_db[] = { }, { { - meFOURCC('I', '4', '2', '0'), - meFOURCC('I', 'Y', 'U', 'V'), + ME_FOURCC('I', '4', '2', '0'), + ME_FOURCC('I', 'Y', 'U', 'V'), 0 }, BUF_VIDEO_I420, @@ -505,8 +497,8 @@ static const video_db_t video_db[] = { }, { { - meFOURCC('S', 'E', 'G', 'A'), - meFOURCC('s', 'e', 'g', 'a'), + ME_FOURCC('S', 'E', 'G', 'A'), + ME_FOURCC('s', 'e', 'g', 'a'), 0 }, BUF_VIDEO_SEGA, @@ -514,8 +506,8 @@ static const video_db_t video_db[] = { }, { { - meFOURCC('m', 'v', 'i', '2'), - meFOURCC('M', 'V', 'I', '2'), + ME_FOURCC('m', 'v', 'i', '2'), + ME_FOURCC('M', 'V', 'I', '2'), 0 }, BUF_VIDEO_MVI2, @@ -523,8 +515,8 @@ static const video_db_t video_db[] = { }, { { - meFOURCC('u', 'c', 'o', 'd'), - meFOURCC('U', 'C', 'O', 'D'), + ME_FOURCC('u', 'c', 'o', 'd'), + ME_FOURCC('U', 'C', 'O', 'D'), 0 }, BUF_VIDEO_UCOD, @@ -532,7 +524,7 @@ static const video_db_t video_db[] = { }, { { - meFOURCC('R', 'V', '1', '0'), + ME_FOURCC('R', 'V', '1', '0'), 0 }, BUF_VIDEO_RV10, @@ -540,7 +532,7 @@ static const video_db_t video_db[] = { }, { { - meFOURCC('R', 'V', '2', '0'), + ME_FOURCC('R', 'V', '2', '0'), 0 }, BUF_VIDEO_RV20, @@ -548,7 +540,7 @@ static const video_db_t video_db[] = { }, { { - meFOURCC('R', 'V', '3', '0'), + ME_FOURCC('R', 'V', '3', '0'), 0 }, BUF_VIDEO_RV30, @@ -556,7 +548,7 @@ static const video_db_t video_db[] = { }, { { - meFOURCC('R', 'V', '4', '0'), + ME_FOURCC('R', 'V', '4', '0'), 0 }, BUF_VIDEO_RV40, @@ -564,7 +556,7 @@ static const video_db_t video_db[] = { }, { { - meFOURCC('H', 'F', 'Y', 'U'), + ME_FOURCC('H', 'F', 'Y', 'U'), 0, }, BUF_VIDEO_HUFFYUV, @@ -572,8 +564,8 @@ static const video_db_t video_db[] = { }, { { - meFOURCC('I', 'M', 'G', ' '), - meFOURCC('g', 'i', 'f', ' '), + ME_FOURCC('I', 'M', 'G', ' '), + ME_FOURCC('g', 'i', 'f', ' '), 0, }, BUF_VIDEO_IMAGE, @@ -588,7 +580,7 @@ static const video_db_t video_db[] = { }, { { - meFOURCC('V','P','5','0'), + ME_FOURCC('V','P','5','0'), 0 }, BUF_VIDEO_VP5, @@ -596,9 +588,9 @@ static const video_db_t video_db[] = { }, { { - meFOURCC('V','P','6','0'), - meFOURCC('V','P','6','1'), - meFOURCC('V','P','6','2'), + ME_FOURCC('V','P','6','0'), + ME_FOURCC('V','P','6','1'), + ME_FOURCC('V','P','6','2'), 0 }, BUF_VIDEO_VP6, @@ -606,7 +598,7 @@ static const video_db_t video_db[] = { }, { { - meFOURCC('8','B', 'P','S'), + ME_FOURCC('8','B', 'P','S'), 0 }, BUF_VIDEO_8BPS, @@ -614,7 +606,7 @@ static const video_db_t video_db[] = { }, { { - meFOURCC('Z','L','I','B'), + ME_FOURCC('Z','L','I','B'), 0 }, BUF_VIDEO_ZLIB, @@ -622,7 +614,7 @@ static const video_db_t video_db[] = { }, { { - meFOURCC('M','S','Z','H'), + ME_FOURCC('M','S','Z','H'), 0 }, BUF_VIDEO_MSZH, @@ -630,7 +622,7 @@ static const video_db_t video_db[] = { }, { { - meFOURCC('A','S','V','1'), + ME_FOURCC('A','S','V','1'), 0 }, BUF_VIDEO_ASV1, @@ -638,7 +630,7 @@ static const video_db_t video_db[] = { }, { { - meFOURCC('A','S','V','2'), + ME_FOURCC('A','S','V','2'), 0 }, BUF_VIDEO_ASV2, @@ -646,9 +638,9 @@ static const video_db_t video_db[] = { }, { { - meFOURCC('a','v','c','1'), - meFOURCC('h','2','6','4'), - meFOURCC('H','2','6','4'), + ME_FOURCC('a','v','c','1'), + ME_FOURCC('h','2','6','4'), + ME_FOURCC('H','2','6','4'), 0 }, BUF_VIDEO_H264, @@ -656,7 +648,7 @@ static const video_db_t video_db[] = { }, { { - meFOURCC('A','A','S','C'), + ME_FOURCC('A','A','S','C'), 0 }, BUF_VIDEO_AASC, @@ -664,7 +656,7 @@ static const video_db_t video_db[] = { }, { { - meFOURCC('q','d','r','w'), + ME_FOURCC('q','d','r','w'), 0 }, BUF_VIDEO_QDRW, @@ -672,7 +664,7 @@ static const video_db_t video_db[] = { }, { { - meFOURCC('L','O','C','O'), + ME_FOURCC('L','O','C','O'), 0 }, BUF_VIDEO_LOCO, @@ -680,7 +672,7 @@ static const video_db_t video_db[] = { }, { { - meFOURCC('U','L','T','I'), + ME_FOURCC('U','L','T','I'), 0 }, BUF_VIDEO_ULTI, @@ -688,7 +680,7 @@ static const video_db_t video_db[] = { }, { { - meFOURCC('W','N','V','1'), + ME_FOURCC('W','N','V','1'), 0 }, BUF_VIDEO_WNV1, @@ -696,8 +688,8 @@ static const video_db_t video_db[] = { }, { { - meFOURCC('P','I','X','L'), - meFOURCC('X','I','X','L'), + ME_FOURCC('P','I','X','L'), + ME_FOURCC('X','I','X','L'), 0 }, BUF_VIDEO_XL, @@ -705,9 +697,9 @@ static const video_db_t video_db[] = { }, { { - meFOURCC('Q','P','E','G'), - meFOURCC('Q','1','.','0'), - meFOURCC('Q','1','.','1'), + ME_FOURCC('Q','P','E','G'), + ME_FOURCC('Q','1','.','0'), + ME_FOURCC('Q','1','.','1'), 0 }, BUF_VIDEO_QPEG, @@ -715,7 +707,7 @@ static const video_db_t video_db[] = { }, { { - meFOURCC('R','T','2','1'), + ME_FOURCC('R','T','2','1'), 0 }, BUF_VIDEO_RT21, @@ -723,7 +715,7 @@ static const video_db_t video_db[] = { }, { { - meFOURCC('F','P','S','1'), + ME_FOURCC('F','P','S','1'), 0 }, BUF_VIDEO_FPS1, @@ -731,7 +723,7 @@ static const video_db_t video_db[] = { }, { { - meFOURCC('T','M','2','0'), + ME_FOURCC('T','M','2','0'), 0 }, BUF_VIDEO_DUCKTM2, @@ -739,7 +731,7 @@ static const video_db_t video_db[] = { }, { { - meFOURCC('C','S','C','D'), + ME_FOURCC('C','S','C','D'), 0 }, BUF_VIDEO_CSCD, @@ -747,7 +739,7 @@ static const video_db_t video_db[] = { }, { { - meFOURCC('Z','M','B','V'), + ME_FOURCC('Z','M','B','V'), 0 }, BUF_VIDEO_ZMBV, @@ -755,7 +747,7 @@ static const video_db_t video_db[] = { }, { { - meFOURCC('K','M','V','C'), + ME_FOURCC('K','M','V','C'), 0 }, BUF_VIDEO_KMVC, @@ -769,7 +761,7 @@ static const audio_db_t audio_db[] = { { { 0x2000, - meFOURCC('m', 's', 0x20, 0x00), + ME_FOURCC('m', 's', 0x20, 0x00), 0 }, BUF_AUDIO_A52, @@ -778,9 +770,9 @@ static const audio_db_t audio_db[] = { { { 0x50, 0x55, - meFOURCC('.','m','p','3'), - meFOURCC('m', 's', 0, 0x55), - meFOURCC('M','P','3',' '), + ME_FOURCC('.','m','p','3'), + ME_FOURCC('m', 's', 0, 0x55), + ME_FOURCC('M','P','3',' '), 0 }, BUF_AUDIO_MPEG, @@ -788,8 +780,8 @@ static const audio_db_t audio_db[] = { }, { { - meFOURCC('t','w','o','s'), - meFOURCC('i','n','2','4'), + ME_FOURCC('t','w','o','s'), + ME_FOURCC('i','n','2','4'), 0 }, BUF_AUDIO_LPCM_BE, @@ -798,8 +790,8 @@ static const audio_db_t audio_db[] = { { { 0x01, - meFOURCC('r','a','w',' '), - meFOURCC('s','o','w','t'), + ME_FOURCC('r','a','w',' '), + ME_FOURCC('s','o','w','t'), 0 }, BUF_AUDIO_LPCM_LE, @@ -850,7 +842,7 @@ static const audio_db_t audio_db[] = { { { 0x02, - meFOURCC('m', 's', 0, 0x02), + ME_FOURCC('m', 's', 0, 0x02), 0 }, BUF_AUDIO_MSADPCM, @@ -859,7 +851,7 @@ static const audio_db_t audio_db[] = { { { 0x11, - meFOURCC('m', 's', 0, 0x11), + ME_FOURCC('m', 's', 0, 0x11), 0 }, BUF_AUDIO_MSIMAADPCM, @@ -877,8 +869,8 @@ static const audio_db_t audio_db[] = { /* these formattags are used by Vorbis ACM encoder and supported by NanDub, a variant of VirtualDub. */ 0x674f, 0x676f, 0x6750, 0x6770, 0x6751, 0x6771, - meFOURCC('O','g','g','S'), - meFOURCC('O','g','g','V'), + ME_FOURCC('O','g','g','S'), + ME_FOURCC('O','g','g','V'), 0 }, BUF_AUDIO_VORBIS, @@ -935,7 +927,7 @@ static const audio_db_t audio_db[] = { }, { { - meFOURCC('i', 'm', 'a', '4'), + ME_FOURCC('i', 'm', 'a', '4'), 0 }, BUF_AUDIO_QTIMAADPCM, @@ -943,8 +935,8 @@ static const audio_db_t audio_db[] = { }, { { - meFOURCC('m', 'a', 'c', '3'), - meFOURCC('M', 'A', 'C', '3'), + ME_FOURCC('m', 'a', 'c', '3'), + ME_FOURCC('M', 'A', 'C', '3'), 0 }, BUF_AUDIO_MAC3, @@ -952,8 +944,8 @@ static const audio_db_t audio_db[] = { }, { { - meFOURCC('m', 'a', 'c', '6'), - meFOURCC('M', 'A', 'C', '6'), + ME_FOURCC('m', 'a', 'c', '6'), + ME_FOURCC('M', 'A', 'C', '6'), 0 }, BUF_AUDIO_MAC6, @@ -961,7 +953,7 @@ static const audio_db_t audio_db[] = { }, { { - meFOURCC('Q', 'D', 'M', 'C'), + ME_FOURCC('Q', 'D', 'M', 'C'), 0 }, BUF_AUDIO_QDESIGN1, @@ -969,7 +961,7 @@ static const audio_db_t audio_db[] = { }, { { - meFOURCC('Q', 'D', 'M', '2'), + ME_FOURCC('Q', 'D', 'M', '2'), 0 }, BUF_AUDIO_QDESIGN2, @@ -978,11 +970,11 @@ static const audio_db_t audio_db[] = { { { 0xFF, - meFOURCC('m', 'p', '4', 'a'), - meFOURCC('M', 'P', '4', 'A'), - meFOURCC('r', 'a', 'a', 'c'), - meFOURCC('r', 'a', 'c', 'p'), - meFOURCC('A', 'A', 'C', ' '), + ME_FOURCC('m', 'p', '4', 'a'), + ME_FOURCC('M', 'P', '4', 'A'), + ME_FOURCC('r', 'a', 'a', 'c'), + ME_FOURCC('r', 'a', 'c', 'p'), + ME_FOURCC('A', 'A', 'C', ' '), 0 }, BUF_AUDIO_AAC, @@ -990,7 +982,7 @@ static const audio_db_t audio_db[] = { }, { { - meFOURCC('d', 'n', 'e', 't'), + ME_FOURCC('d', 'n', 'e', 't'), 0 }, BUF_AUDIO_DNET, @@ -998,7 +990,7 @@ static const audio_db_t audio_db[] = { }, { { - meFOURCC('s', 'i', 'p', 'r'), + ME_FOURCC('s', 'i', 'p', 'r'), 0 }, BUF_AUDIO_SIPRO, @@ -1006,7 +998,7 @@ static const audio_db_t audio_db[] = { }, { { - meFOURCC('c', 'o', 'o', 'k'), + ME_FOURCC('c', 'o', 'o', 'k'), 0 }, BUF_AUDIO_COOK, @@ -1014,7 +1006,7 @@ static const audio_db_t audio_db[] = { }, { { - meFOURCC('a', 't', 'r', 'c'), + ME_FOURCC('a', 't', 'r', 'c'), 0 }, BUF_AUDIO_ATRK, @@ -1022,7 +1014,7 @@ static const audio_db_t audio_db[] = { }, { { - meFOURCC('Q', 'c', 'l', 'p'), + ME_FOURCC('Q', 'c', 'l', 'p'), 0 }, BUF_AUDIO_QCLP, @@ -1031,7 +1023,7 @@ static const audio_db_t audio_db[] = { { { 0x7, - meFOURCC('u', 'l', 'a', 'w'), + ME_FOURCC('u', 'l', 'a', 'w'), 0 }, BUF_AUDIO_MULAW, @@ -1040,7 +1032,7 @@ static const audio_db_t audio_db[] = { { { 0x6, - meFOURCC('a', 'l', 'a', 'w'), + ME_FOURCC('a', 'l', 'a', 'w'), 0 }, BUF_AUDIO_ALAW, @@ -1048,7 +1040,7 @@ static const audio_db_t audio_db[] = { }, { { - meFOURCC('a', 'g', 's', 'm'), + ME_FOURCC('a', 'g', 's', 'm'), 0 }, BUF_AUDIO_GSM610, @@ -1070,7 +1062,7 @@ static const audio_db_t audio_db[] = { }, { { - meFOURCC('l', 'p', 'c', 'J'), + ME_FOURCC('l', 'p', 'c', 'J'), 0 }, BUF_AUDIO_14_4, @@ -1078,7 +1070,7 @@ static const audio_db_t audio_db[] = { }, { { - meFOURCC('2', '8', '_', '8'), + ME_FOURCC('2', '8', '_', '8'), 0 }, BUF_AUDIO_28_8, @@ -1093,7 +1085,7 @@ static const audio_db_t audio_db[] = { }, { { - meFOURCC('a', 'l', 'a', 'c'), + ME_FOURCC('a', 'l', 'a', 'c'), }, BUF_AUDIO_ALAC, "Apple Lossless Audio Codec" @@ -1143,7 +1135,7 @@ static uint32_t cached_buf_type=0; return 0; } -char * _x_buf_video_name( uint32_t buf_type ) { +const char *_x_buf_video_name( uint32_t buf_type ) { int i; buf_type &= 0xffff0000; @@ -1177,7 +1169,7 @@ static uint32_t cached_buf_type=0; return 0; } -char * _x_buf_audio_name( uint32_t buf_type ) { +const char *_x_buf_audio_name( uint32_t buf_type ) { int i; buf_type &= 0xffff0000; @@ -1218,3 +1210,4 @@ void _x_waveformatex_le2me( xine_waveformatex *wavex ) { wavex->wBitsPerSample = le2me_16(wavex->wBitsPerSample); wavex->cbSize = le2me_16(wavex->cbSize); } + diff --git a/src/xine-engine/configfile.h b/src/xine-engine/configfile.h index e21b08db0..22a544c00 100644 --- a/src/xine-engine/configfile.h +++ b/src/xine-engine/configfile.h @@ -37,7 +37,7 @@ extern "C" { #define CONFIG_FILE_VERSION 2 -/* +/** * config entries above this experience * level must never be changed from MRL */ @@ -54,33 +54,32 @@ struct cfg_entry_s { char *key; int type; - /* type unknown */ + /** user experience level */ + int exp_level; + + /** type unknown */ char *unknown_value; - /* type string */ + /** type string */ char *str_value; char *str_default; - /* common to range, enum, num, bool: */ - + /** common to range, enum, num, bool: */ int num_value; int num_default; - /* type range specific: */ + /** type range specific: */ int range_min; int range_max; - /* type enum specific: */ + /** type enum specific: */ char **enum_values; - /* help info for the user */ + /** help info for the user */ char *description; char *help; - /* user experience level */ - int exp_level; - - /* callback function and data for live changeable values */ + /** callback function and data for live changeable values */ xine_config_cb_t callback; void *callback_data; }; @@ -153,17 +152,17 @@ struct config_values_s { xine_config_cb_t changed_cb, void *cb_data); - /* convenience function to update range, enum, num and bool values */ + /** convenience function to update range, enum, num and bool values */ void (*update_num) (config_values_t *self, const char *key, int value); - /* convenience function to update string values */ + /** convenience function to update string values */ void (*update_string) (config_values_t *self, const char *key, const char *value); - /* small utility function for enum handling */ + /** small utility function for enum handling */ int (*parse_enum) (const char *str, const char **values); - /* - * lookup config entries + /** + * @brief lookup config entries * * remember to call the changed_cb if it exists * and you changed the value of this item @@ -171,12 +170,12 @@ struct config_values_s { cfg_entry_t* (*lookup_entry) (config_values_t *self, const char *key); - /* + /** * unregister callback function */ void (*unregister_callback) (config_values_t *self, const char *key); - /* + /** * dispose of all config entries in memory */ void (*dispose) (config_values_t *self); @@ -186,27 +185,29 @@ struct config_values_s { */ cfg_entry_t *first, *last, *cur; - /* + /** * mutex for modification to the config */ pthread_mutex_t config_lock; - /* + /** * current config file's version number */ int current_version; }; -/* - * allocate and init a new xine config object +/** + * @brief allocate and init a new xine config object + * @internal */ -config_values_t *_x_config_init (void) XINE_PROTECTED; +config_values_t *_x_config_init (void); -/* - * interpret stream_setup part of mrls for config value changes +/** + * @brief interpret stream_setup part of mrls for config value changes + * @internal */ -int _x_config_change_opt(config_values_t *config, const char *opt) XINE_PROTECTED; +int _x_config_change_opt(config_values_t *config, const char *opt); #ifdef __cplusplus diff --git a/src/xine-engine/input_cache.c b/src/xine-engine/input_cache.c index 2baa67c7c..83ec4ae33 100644 --- a/src/xine-engine/input_cache.c +++ b/src/xine-engine/input_cache.c @@ -60,8 +60,9 @@ typedef struct { /* * read data from input plugin and write it into file */ -static off_t cache_plugin_read(input_plugin_t *this_gen, char *buf, off_t len) { +static off_t cache_plugin_read(input_plugin_t *this_gen, void *buf_gen, off_t len) { cache_input_plugin_t *this = (cache_input_plugin_t *)this_gen; + char *buf = (char *)buf_gen; off_t read_len = 0; off_t main_read; diff --git a/src/xine-engine/input_rip.c b/src/xine-engine/input_rip.c index 0c185aa1b..a8268552a 100644 --- a/src/xine-engine/input_rip.c +++ b/src/xine-engine/input_rip.c @@ -98,8 +98,9 @@ static off_t min_off(off_t a, off_t b) { /* * read data from input plugin and write it into file */ -static off_t rip_plugin_read(input_plugin_t *this_gen, char *buf, off_t len) { +static off_t rip_plugin_read(input_plugin_t *this_gen, void *buf_gen, off_t len) { rip_input_plugin_t *this = (rip_input_plugin_t *)this_gen; + char *buf = (char *)buf_gen; off_t retlen, npreview, nread, nwrite, nread_orig, nread_file; lprintf("reading %"PRId64" bytes (curpos = %"PRId64", savepos = %"PRId64")\n", len, this->curpos, this->savepos); diff --git a/src/xine-engine/load_plugins.c b/src/xine-engine/load_plugins.c index 71cb19d3b..19a8b4e05 100644 --- a/src/xine-engine/load_plugins.c +++ b/src/xine-engine/load_plugins.c @@ -40,6 +40,8 @@ #include <ctype.h> #include <signal.h> +#include <basedir.h> + #define LOG_MODULE "load_plugins" #define LOG_VERBOSE @@ -92,6 +94,7 @@ static void remove_segv_handler(void){ #endif #endif /* 0 */ +#define CACHE_CATALOG_VERSION 2 static const int plugin_iface_versions[] = { INPUT_PLUGIN_IFACE_VERSION, @@ -313,7 +316,6 @@ static void _insert_node (xine_t *this, const input_info_t *input_old; uint32_t *types; char key[80]; - char desc[100]; int i; _x_assert(list); @@ -377,13 +379,8 @@ static void _insert_node (xine_t *this, entry->priority = decoder_new->priority = decoder_old->priority; snprintf(key, sizeof(key), "engine.decoder_priorities.%s", info->id); - snprintf(desc, sizeof(desc), _("priority for %s decoder"), info->id); - /* write the description on the heap because the config system - * does not strdup() it, so we have to provide a different pointer - * for each decoder */ for (i = 0; catalog->prio_desc[i]; i++); - catalog->prio_desc[i] = malloc(strlen(desc) + 1); - strcpy(catalog->prio_desc[i], desc); + asprintf(&catalog->prio_desc[i], _("priority for %s decoder"), info->id); this->config->register_num (this->config, key, 0, @@ -945,7 +942,7 @@ static void load_plugin_list(FILE *fp, xine_sarray_t *plugins) { file = xine_xmalloc(sizeof(plugin_file_t)); node->file = file; file->filename = strdup(line+1); - node->info = xine_xmalloc(2*sizeof(plugin_info_t)); + node->info = xine_xcalloc(2, sizeof(plugin_info_t)); node->info[1].type = PLUGIN_NONE; decoder_info = NULL; vo_info = NULL; @@ -1029,7 +1026,7 @@ static void load_plugin_list(FILE *fp, xine_sarray_t *plugins) { for( s = value, i = 0; s && sscanf(s," %lu",&lu) > 0; i++ ) { s = strchr(s+1, ' '); } - decoder_info->supported_types = xine_xmalloc((i+1)*sizeof(uint32_t)); + decoder_info->supported_types = xine_xcalloc((i+1), sizeof(uint32_t)); for( s = value, i = 0; s && sscanf(s," %lu",&lu) > 0; i++ ) { decoder_info->supported_types[i] = lu; s = strchr(s+1, ' '); @@ -1062,27 +1059,68 @@ static void load_plugin_list(FILE *fp, xine_sarray_t *plugins) { } } +/** + * @brief Returns the complete filename for the plugins' cache file + * @param this Instance pointer, used for logging and libxdg-basedir. + * @param createdir If not zero, create the directory structure in which + * the file has to reside. + * @return If createdir was not zero, returns NULL if the directory hasn't + * been created; otherwise always returns a new string with the + * name of the cachefile. + * @internal + * + * @see XDG Base Directory specification: + * http://standards.freedesktop.org/basedir-spec/latest/index.html + */ +static char *catalog_filename(xine_t *this, int createdir) { + const char *const xdg_cache_home = xdgCacheHome(this->basedir_handle); + char *cachefile = NULL; + + cachefile = xine_xmalloc( strlen(xdg_cache_home) + sizeof("/"PACKAGE"/plugins.cache") ); + strcpy(cachefile, xdg_cache_home); + + /* If we're going to create the directory structure, we concatenate + * piece by piece the path, so that we can try to create all the + * directories. + * If we don't need to create anything, we just concatenate the + * whole path at once. + */ + if ( createdir ) { + int result = 0; + + result = mkdir( cachefile, 0700 ); + if ( result != 0 && errno != EEXIST ) { + /** @todo Convert this to use xine's log facility */ + fprintf(stderr, _("Unable to create %s directory: %s\n"), cachefile, strerror(errno)); + free(cachefile); + return NULL; + } + + strcat(cachefile, "/"PACKAGE); + result = mkdir( cachefile, 0700 ); + if ( result != 0 && errno != EEXIST ) { + /** @todo Convert this to use xine's log facility */ + fprintf(stderr, _("Unable to create %s directory: %s\n"), cachefile, strerror(errno)); + free(cachefile); + return NULL; + } + + strcat(cachefile, "/plugins.cache"); + + } else + strcat(cachefile, "/"PACKAGE"/plugins.cache"); + + return cachefile; +} /* * save catalog to cache file */ static void save_catalog (xine_t *this) { - FILE *fp; - char *cachefile, *dirfile; - const char *relname = CACHE_CATALOG_FILE; - const char *dirname = CACHE_CATALOG_DIR; - - cachefile = (char *) xine_xmalloc(strlen(xine_get_homedir()) + - strlen(relname) + 2); - sprintf(cachefile, "%s/%s", xine_get_homedir(), relname); - - /* make sure homedir (~/.xine) exists */ - dirfile = (char *) xine_xmalloc(strlen(xine_get_homedir()) + - strlen(dirname) + 2); - sprintf(dirfile, "%s/%s", xine_get_homedir(), dirname); - mkdir (dirfile, 0755); - free (dirfile); + char *const cachefile = catalog_filename(this, 1); + + if ( ! cachefile ) return; if( (fp = fopen(cachefile,"w")) != NULL ) { int i; @@ -1104,13 +1142,9 @@ static void save_catalog (xine_t *this) { static void load_cached_catalog (xine_t *this) { FILE *fp; - char *cachefile; - const char *relname = CACHE_CATALOG_FILE; - - cachefile = (char *) xine_xmalloc(strlen(xine_get_homedir()) + - strlen(relname) + 2); - sprintf(cachefile, "%s/%s", xine_get_homedir(), relname); - + char *const cachefile = catalog_filename(this, 0); + /* It can't return NULL without creating directories */ + if( (fp = fopen(cachefile,"r")) != NULL ) { load_plugin_list (fp, this->plugin_catalog->cache_list); fclose(fp); @@ -2227,7 +2261,7 @@ const char *const *xine_list_post_plugins(xine_t *xine) { return catalog->ids; } -const char *const *xine_list_post_plugins_typed(xine_t *xine, int type) { +const char *const *xine_list_post_plugins_typed(xine_t *xine, uint32_t type) { plugin_catalog_t *catalog = xine->plugin_catalog; plugin_node_t *node; int i; diff --git a/src/xine-engine/metronom.c b/src/xine-engine/metronom.c index 5d3e0a12d..328d2cb3c 100644 --- a/src/xine-engine/metronom.c +++ b/src/xine-engine/metronom.c @@ -849,7 +849,8 @@ static void metronom_unregister_scr (metronom_clock_t *this, scr_plugin_t *scr) this->scr_master = get_master_scr(this); } -static int metronom_sync_loop (metronom_clock_t *this) { +static void *metronom_sync_loop (void *const this_gen) { + metronom_clock_t *const this = (metronom_clock_t *const)this_gen; struct timeval tv; struct timespec ts; @@ -872,7 +873,7 @@ static int metronom_sync_loop (metronom_clock_t *this) { pthread_mutex_unlock (&this->lock); } - return 0; + return NULL; } static void metronom_exit (metronom_t *this) { @@ -988,7 +989,7 @@ metronom_clock_t *_x_metronom_clock_init(xine_t *xine) this->thread_running = 1; if ((err = pthread_create(&this->sync_thread, NULL, - (void*(*)(void*)) metronom_sync_loop, this)) != 0) + metronom_sync_loop, this)) != 0) xprintf(this->xine, XINE_VERBOSITY_NONE, "cannot create sync thread (%s)\n", strerror(err)); diff --git a/src/xine-engine/metronom.h b/src/xine-engine/metronom.h index 20e31117c..77919f16e 100644 --- a/src/xine-engine/metronom.h +++ b/src/xine-engine/metronom.h @@ -333,8 +333,6 @@ metronom_clock_t *_x_metronom_clock_init(xine_t *xine) XINE_PROTECTED; struct scr_plugin_s { - int interface_version; - int (*get_priority) (scr_plugin_t *self); /* @@ -355,6 +353,8 @@ struct scr_plugin_s void (*exit) (scr_plugin_t *self); metronom_clock_t *clock; + + int interface_version; }; #ifdef __cplusplus diff --git a/src/xine-engine/osd.c b/src/xine-engine/osd.c index ef888e7a4..1587b76e4 100644 --- a/src/xine-engine/osd.c +++ b/src/xine-engine/osd.c @@ -40,6 +40,8 @@ # include <iconv.h> #endif +#include <basedir.h> + #define LOG_MODULE "osd" #define LOG_VERBOSE /* @@ -816,6 +818,93 @@ static int osd_renderer_unload_font(osd_renderer_t *this, char *fontname ) { } #ifdef HAVE_FT2 + +# ifdef HAVE_FONTCONFIG +/** + * @brief Look up a font name using FontConfig library + * @param osd The OSD object to load the font for. + * @param fontname Name of the font to look up. + * @param size Size of the font to look for. + * + * @return If the lookup was done correctly, a non-zero value is returned. + */ +static int osd_lookup_fontconfig( osd_object_t *osd, const char *const fontname, const int size ) { + FcPattern *pat = NULL, *match = NULL; + FcFontSet *fs = FcFontSetCreate(); + FcResult result; + + pat = FcPatternBuild(NULL, FC_FAMILY, FcTypeString, fontname, FC_SIZE, FcTypeDouble, (double)size, NULL); + FcConfigSubstitute(NULL, pat, FcMatchPattern); + FcDefaultSubstitute(pat); + + match = FcFontMatch(NULL, pat, &result); + FcPatternDestroy(pat); + + if ( ! match ) { + FcFontSetDestroy(fs); + xprintf(osd->renderer->stream->xine, XINE_VERBOSITY_LOG, + _("osd: error matching font %s with FontConfig"), fontname); + return 0; + } + FcFontSetAdd(fs, match); + + if ( fs->nfont != 0 ) { + FcChar8 *filename = NULL; + FcPatternGetString(fs->fonts[0], FC_FILE, 0, &filename); + if ( ! FT_New_Face(osd->ft2->library, (const char*)filename, 0, &osd->ft2->face) ) { + FcFontSetDestroy(fs); + return 1; + } + + xprintf(osd->renderer->stream->xine, XINE_VERBOSITY_LOG, + _("osd: error loading font %s with FontConfig"), fontname); + return 0; + } else { + xprintf(osd->renderer->stream->xine, XINE_VERBOSITY_LOG, + _("osd: error looking up font %s with FontConfig"), fontname); + return 0; + } +} +# endif /* HAVE_FONTCONFIG */ + +/** + * @brief Look up a font file using XDG data directories. + * @param osd The OSD object to load the font for. + * @param fontname Name (absolute or relative) of the font to look up. + * + * @return If the lookup was done correctly, a non-zero value is returned. + * + * @see XDG Base Directory specification: + * http://standards.freedesktop.org/basedir-spec/latest/index.html + */ +static int osd_lookup_xdg( osd_object_t *osd, const char *const fontname ) { + const char *const *data_dirs = xdgSearchableDataDirectories(osd->renderer->stream->xine->basedir_handle); + + /* try load font from current directory or from an absolute path */ + if ( FT_New_Face(osd->ft2->library, fontname, 0, &osd->ft2->face) == FT_Err_Ok ) + return 1; + + if ( data_dirs ) + while( (*data_dirs) && *(*data_dirs) ) { + FT_Error fte = FT_Err_Ok; + char *fontpath = NULL; + asprintf(&fontpath, "%s/"PACKAGE"/fonts/%s", *data_dirs, fontname); + + fte = FT_New_Face(osd->ft2->library, fontpath, 0, &osd->ft2->face); + + free(fontpath); + + if ( fte == FT_Err_Ok ) + return 1; + + data_dirs++; + } + + xprintf(osd->renderer->stream->xine, XINE_VERBOSITY_LOG, + _("osd: error loading font %s with in XDG data directories.\n"), fontname); + return 0; +} + static int osd_set_font_freetype2( osd_object_t *osd, const char *fontname, int size ) { if (!osd->ft2) { osd->ft2 = xine_xmalloc(sizeof(osd_ft2context_t)); @@ -828,68 +917,19 @@ static int osd_set_font_freetype2( osd_object_t *osd, const char *fontname, int } } + do { /* while 0 */ #ifdef HAVE_FONTCONFIG - do { - FcPattern *pat = NULL, *match = NULL; - FcFontSet *fs = FcFontSetCreate(); - FcResult result; - - pat = FcPatternBuild(NULL, FC_FAMILY, FcTypeString, fontname, FC_SIZE, FcTypeDouble, (double)size, NULL); - FcConfigSubstitute(NULL, pat, FcMatchPattern); - FcDefaultSubstitute(pat); - - match = FcFontMatch(NULL, pat, &result); - FcPatternDestroy(pat); - - if ( ! match ) { - FcFontSetDestroy(fs); - xprintf(osd->renderer->stream->xine, XINE_VERBOSITY_LOG, - _("osd: error matching font %s with FontConfig"), fontname); + if ( osd_lookup_fontconfig(osd, fontname, size) ) break; - } - FcFontSetAdd(fs, match); - - if ( fs->nfont != 0 ) { - FcChar8 *filename = NULL; - FcPatternGetString(fs->fonts[0], FC_FILE, 0, &filename); - if ( ! FT_New_Face(osd->ft2->library, (const char*)filename, 0, &osd->ft2->face) ) { - FcFontSetDestroy(fs); - goto end; - } - - xprintf(osd->renderer->stream->xine, XINE_VERBOSITY_LOG, - _("osd: error loading font %s with FontConfig"), fontname); - } else { - xprintf(osd->renderer->stream->xine, XINE_VERBOSITY_LOG, - _("osd: error looking up font %s with FontConfig"), fontname); - } - } while(0); #endif - { - char pathname[1024]; - /* try load font from current directory */ - if ( !FT_New_Face(osd->ft2->library, fontname, 0, &osd->ft2->face) ) - goto end; - - /* try load font from home directory */ - snprintf(pathname, 1024, "%s/.xine/fonts/%s", xine_get_homedir(), fontname); - if ( !FT_New_Face(osd->ft2->library, pathname, 0, &osd->ft2->face) ) - goto end; - - /* try load font from xine font directory */ - snprintf(pathname, 1024, "%s/%s", XINE_FONTDIR, fontname); - if ( !FT_New_Face(osd->ft2->library, pathname, 0, &osd->ft2->face) ) - goto end; - - xprintf(osd->renderer->stream->xine, XINE_VERBOSITY_LOG, - _("osd: error loading font %s with ft2\n"), fontname); - } + if ( osd_lookup_xdg(osd, fontname) ) + break; - free(osd->ft2); - osd->ft2 = NULL; - return 0; + free(osd->ft2); + osd->ft2 = NULL; + return 0; + } while(0); - end: if (FT_Set_Pixel_Sizes(osd->ft2->face, 0, size)) { xprintf(osd->renderer->stream->xine, XINE_VERBOSITY_LOG, _("osd: error setting font size (no scalable font?)\n")); @@ -1577,7 +1617,6 @@ static uint32_t osd_get_capabilities (osd_object_t *osd) { osd_renderer_t *_x_osd_renderer_init( xine_stream_t *stream ) { osd_renderer_t *this; - char str[1024]; this = xine_xmalloc(sizeof(osd_renderer_t)); this->stream = stream; @@ -1588,12 +1627,22 @@ osd_renderer_t *_x_osd_renderer_init( xine_stream_t *stream ) { /* * load available fonts */ + { + const char *const *data_dirs = xdgSearchableDataDirectories(stream->xine->basedir_handle); + if ( data_dirs ) + while( (*data_dirs) && *(*data_dirs) ) { + /* sizeof("") takes care of the final NUL byte */ + char *fontpath = xine_xmalloc( strlen(*data_dirs) + sizeof("/"PACKAGE"/fonts/") ); + strcpy(fontpath, *data_dirs); + strcat(fontpath, "/"PACKAGE"/fonts/"); - osd_preload_fonts (this, XINE_FONTDIR); - - snprintf (str, 1024, "%s/.xine/fonts", xine_get_homedir ()); + osd_preload_fonts(this, fontpath); - osd_preload_fonts (this, str); + free(fontpath); + + data_dirs++; + } + } this->textpalette = this->stream->xine->config->register_enum (this->stream->xine->config, "ui.osd.text_palette", 0, diff --git a/src/xine-engine/osd.h b/src/xine-engine/osd.h index 38b5d1fdd..7b04c0a17 100644 --- a/src/xine-engine/osd.h +++ b/src/xine-engine/osd.h @@ -56,8 +56,6 @@ struct osd_object_s { uint32_t color[OVL_PALETTE_SIZE]; /* color lookup table */ uint8_t trans[OVL_PALETTE_SIZE]; /* mixer key table */ - int32_t handle; - #ifdef HAVE_ICONV iconv_t cd; /* iconv handle of encoding */ char *encoding; /* name of encoding */ @@ -65,6 +63,8 @@ struct osd_object_s { osd_font_t *font; osd_ft2context_t *ft2; + + int32_t handle; }; /* this one is public */ @@ -73,6 +73,8 @@ struct xine_osd_s { }; struct osd_renderer_s { + + xine_stream_t *stream; /* * open a new osd object. this will allocated an empty (all zero) drawing @@ -218,8 +220,6 @@ struct osd_renderer_s { osd_object_t *osds; /* instances of osd */ osd_font_t *fonts; /* loaded fonts */ int textpalette; /* default textpalette */ - - xine_stream_t *stream; }; diff --git a/src/xine-engine/plugin_catalog.h b/src/xine-engine/plugin_catalog.h index a28321760..fd9afb959 100644 --- a/src/xine-engine/plugin_catalog.h +++ b/src/xine-engine/plugin_catalog.h @@ -37,16 +37,12 @@ /* the engine takes this many plugins for one stream type */ #define PLUGINS_PER_TYPE 10 -#define CACHE_CATALOG_VERSION 2 -#define CACHE_CATALOG_FILE ".xine/catalog.cache" -#define CACHE_CATALOG_DIR ".xine" - typedef struct { char *filename; off_t filesize; time_t filemtime; - int ref; /* count number of classes */ void *lib_handle; + int ref; /* count number of classes */ int no_unload; /* set if the file can't be unloaded */ } plugin_file_t ; diff --git a/src/xine-engine/post.c b/src/xine-engine/post.c index 5d8d67037..e54d2234f 100644 --- a/src/xine-engine/post.c +++ b/src/xine-engine/post.c @@ -147,6 +147,14 @@ static void post_video_flush(xine_video_port_t *port_gen) { if (port->port_lock) pthread_mutex_unlock(port->port_lock); } +static void post_video_trigger_drawing(xine_video_port_t *port_gen) { + post_video_port_t *port = (post_video_port_t *)port_gen; + + if (port->port_lock) pthread_mutex_lock(port->port_lock); + port->original_port->trigger_drawing(port->original_port); + if (port->port_lock) pthread_mutex_unlock(port->port_lock); +} + static int post_video_status(xine_video_port_t *port_gen, xine_stream_t *stream, int *width, int *height, int64_t *img_duration) { post_video_port_t *port = (post_video_port_t *)port_gen; @@ -190,6 +198,7 @@ static int post_video_rewire(xine_post_out_t *output_gen, void *data) { if (!new_port) return 0; + this->running_ticket->lock_port_rewiring(this->running_ticket, -1); this->running_ticket->revoke(this->running_ticket, 1); if (input_port->original_port->status(input_port->original_port, input_port->stream, @@ -200,6 +209,7 @@ static int post_video_rewire(xine_post_out_t *output_gen, void *data) { input_port->original_port = new_port; this->running_ticket->issue(this->running_ticket, 1); + this->running_ticket->unlock_port_rewiring(this->running_ticket); return 1; } @@ -221,6 +231,7 @@ post_video_port_t *_x_post_intercept_video_port(post_plugin_t *post, xine_video_ port->new_port.exit = post_video_exit; port->new_port.get_overlay_manager = post_video_get_overlay_manager; port->new_port.flush = post_video_flush; + port->new_port.trigger_drawing = post_video_trigger_drawing; port->new_port.status = post_video_status; port->new_port.get_property = post_video_get_property; port->new_port.set_property = post_video_set_property; @@ -380,10 +391,11 @@ vo_frame_t *_x_post_intercept_video_frame(vo_frame_t *frame, post_video_port_t * port->new_frame->free ? port->new_frame->free : post_frame_free; new_frame->dispose = port->new_frame->dispose ? port->new_frame->dispose : post_frame_dispose; - - if (!port->new_frame->draw) { + + if (!port->new_frame->draw || (port->route_preprocessing_procs && port->route_preprocessing_procs(port, frame))) { /* draw will most likely modify the frame, so the decoder - * should only request preprocessing when there is no new draw */ + * should only request preprocessing when there is no new draw + * but route_preprocessing_procs() can override this decision */ if (frame->proc_frame && !new_frame->proc_frame) new_frame->proc_frame = post_frame_proc_frame; if (frame->proc_slice && !new_frame->proc_slice) @@ -700,6 +712,7 @@ static int post_audio_rewire(xine_post_out_t *output_gen, void *data) { if (!new_port) return 0; + this->running_ticket->lock_port_rewiring(this->running_ticket, -1); this->running_ticket->revoke(this->running_ticket, 1); if (input_port->original_port->status(input_port->original_port, input_port->stream, @@ -710,6 +723,7 @@ static int post_audio_rewire(xine_post_out_t *output_gen, void *data) { input_port->original_port = new_port; this->running_ticket->issue(this->running_ticket, 1); + this->running_ticket->unlock_port_rewiring(this->running_ticket); return 1; } diff --git a/src/xine-engine/post.h b/src/xine-engine/post.h index b06c7930a..6186f31e0 100644 --- a/src/xine-engine/post.h +++ b/src/xine-engine/post.h @@ -89,9 +89,6 @@ struct post_plugin_s { */ void (*dispose) (post_plugin_t *this); - /* has dispose been called */ - int dispose_pending; - /* plugins don't have to init the stuff below */ /* @@ -116,6 +113,9 @@ struct post_plugin_s { /* used by plugin loader */ void *node; + + /* has dispose been called */ + int dispose_pending; }; /* helper function to initialize a post_plugin_t */ @@ -177,6 +177,13 @@ struct post_video_port_s { /* the new frame function pointers */ vo_frame_t *new_frame; + /* if you want to decide yourself, whether the preprocessing functions + * should still be routed when draw is intercepted, fill in this + * function; _x_post_intercept_video_frame() acts as a template method + * and asks your function; return a boolean; the default is _not_ to + * route preprocessing functions when draw is intercepted */ + int (*route_preprocessing_procs)(post_video_port_t *self, vo_frame_t *frame); + /* if you want to decide yourself, whether the overlay manager should * be intercepted, fill in this function; get_overlay_manager() acts as * a template method and asks your function; return a boolean; @@ -287,16 +294,16 @@ struct post_audio_port_s { /* the original port to call its functions from inside yours */ xine_audio_port_t *original_port; - /* usage counter: how many objects are floating around that need - * these pointers to exist */ - int usage_count; - pthread_mutex_t usage_lock; - /* the stream we are being fed by; NULL means no stream is connected; * this may be an anonymous stream */ xine_stream_t *stream; - /* some values remembered by port->open() */ + pthread_mutex_t usage_lock; + /* usage counter: how many objects are floating around that need + * these pointers to exist */ + int usage_count; + + /* some values remembered by (port->open) () */ uint32_t bits; uint32_t rate; uint32_t mode; diff --git a/src/xine-engine/refcounter.h b/src/xine-engine/refcounter.h index 87abd6321..a662a974e 100644 --- a/src/xine-engine/refcounter.h +++ b/src/xine-engine/refcounter.h @@ -28,9 +28,9 @@ typedef struct { pthread_mutex_t lock; - int count; void* object; /* referenced object */ void (*destructor)(void *); /* object destructor */ + int count; } refcounter_t; typedef void (*refcounter_destructor)(void*); diff --git a/src/xine-engine/scratch.c b/src/xine-engine/scratch.c index 38b606b84..98fed2cdd 100644 --- a/src/xine-engine/scratch.c +++ b/src/xine-engine/scratch.c @@ -105,15 +105,11 @@ static void scratch_dispose (scratch_buffer_t *this) { scratch_buffer_t *_x_new_scratch_buffer (int num_lines) { scratch_buffer_t *this; - int i; this = xine_xmalloc (sizeof (scratch_buffer_t)); - this->lines = xine_xmalloc (sizeof (char *) * (num_lines + 1)); - this->ordered = xine_xmalloc (sizeof (char *) * (num_lines + 1)); - - for (i = 0; i <= num_lines; i++) - this->lines[i] = this->ordered[i] = NULL; + this->lines = xine_xcalloc ((num_lines + 1), sizeof(char*)); + this->ordered = xine_xcalloc ((num_lines + 1), sizeof(char*)); this->scratch_printf = scratch_printf; this->get_content = scratch_get_content; diff --git a/src/xine-engine/spu.c b/src/xine-engine/spu.c new file mode 100644 index 000000000..813300fb0 --- /dev/null +++ b/src/xine-engine/spu.c @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2007 the xine project + * + * This file is part of xine, a free video player. + * + * xine is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * xine is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +#include "xine_internal.h" +#include "spu.h" + +#define BLACK_OPACITY 67 +#define COLOUR_OPACITY 100 + +static void no_op (void *user_data, xine_cfg_entry_t *entry) +{ +} + +void _x_spu_misc_init (xine_t *this) +{ + this->config->register_range (this->config, "subtitles.bitmap.black_opacity", + BLACK_OPACITY, 0, 100, + _("opacity for the black parts of bitmapped subtitles"), + NULL, + 10, no_op, NULL); + this->config->register_range (this->config, "subtitles.bitmap.colour_opacity", + COLOUR_OPACITY, 0, 100, + _("opacity for the colour parts of bitmapped subtitles"), + NULL, + 10, no_op, NULL); +} + +void _x_spu_get_opacity (xine_t *this, xine_spu_opacity_t *opacity) +{ + cfg_entry_t *entry; + + entry = this->config->lookup_entry (this->config, "subtitles.bitmap.black_opacity"); + opacity->black = entry ? entry->num_value : BLACK_OPACITY; + entry = this->config->lookup_entry (this->config, "subtitles.bitmap.colour_opacity"); + opacity->colour = entry ? entry->num_value : COLOUR_OPACITY; +} + +int _x_spu_calculate_opacity (const clut_t *clut, uint8_t trans, const xine_spu_opacity_t *opacity) +{ + int value = (clut->y == 0 || (clut->y == 16 && clut->cb == 128 && clut->cr == 128)) + ? opacity->black + : opacity->colour; + return value * (255 - trans) / 100; +} diff --git a/src/xine-engine/spu.h b/src/xine-engine/spu.h new file mode 100644 index 000000000..daba7866b --- /dev/null +++ b/src/xine-engine/spu.h @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2007 the xine project + * + * This file is part of xine, a free video player. + * + * xine is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * xine is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +#ifndef XINE_UTILS_SPU_H +#define XINE_UTILS_SPU_H + +#ifndef XINE_PROTECTED +#define XINE_PROTECTED +#endif + +typedef struct xine_spu_opacity_s xine_spu_opacity_t; + +struct xine_spu_opacity_s { + uint8_t black, colour; +}; + +void _x_spu_misc_init (xine_t *); + +void _x_spu_get_opacity (xine_t *, xine_spu_opacity_t *) XINE_PROTECTED; + +/* in: trans = 0..255, 0=opaque + * out: 0..255, 0=transparent + */ +int _x_spu_calculate_opacity (const clut_t *, uint8_t trans, const xine_spu_opacity_t *) XINE_PROTECTED; + +#endif diff --git a/src/xine-engine/video_decoder.c b/src/xine-engine/video_decoder.c index c371d7657..c88e01714 100644 --- a/src/xine-engine/video_decoder.c +++ b/src/xine-engine/video_decoder.c @@ -25,6 +25,7 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <unistd.h> #define XINE_ENGINE_INTERNAL @@ -107,6 +108,15 @@ static void *video_decoder_loop (void *stream_gen) { int prof_video_decode = -1; int prof_spu_decode = -1; uint32_t buftype_unknown = 0; + +#ifndef WIN32 + /* nice(-value) will fail silently for normal users. + * however when running as root this may provide smoother + * playback. follow the link for more information: + * http://cambuca.ldhs.cetuc.puc-rio.br/~miguel/multimedia_sim/ + */ + nice(-1); +#endif /* WIN32 */ if (prof_video_decode == -1) prof_video_decode = xine_profiler_allocate_slot ("video decoder"); diff --git a/src/xine-engine/video_out.c b/src/xine-engine/video_out.c index b961c6060..575017301 100644 --- a/src/xine-engine/video_out.c +++ b/src/xine-engine/video_out.c @@ -69,6 +69,7 @@ typedef struct { vo_frame_t *first; vo_frame_t *last; int num_buffers; + int num_buffers_max; int locked_for_read; pthread_mutex_t mutex; @@ -126,9 +127,14 @@ typedef struct { int current_width, current_height; int64_t current_duration; + int frame_drop_limit_max; int frame_drop_limit; int frame_drop_cpt; + int frame_drop_suggested; int crop_left, crop_right, crop_top, crop_bottom; + pthread_mutex_t trigger_drawing_mutex; + pthread_cond_t trigger_drawing_cond; + int trigger_drawing; } vos_t; @@ -142,9 +148,11 @@ static img_buf_fifo_t *vo_new_img_buf_queue () { queue = (img_buf_fifo_t *) xine_xmalloc (sizeof (img_buf_fifo_t)); if( queue ) { - queue->first = NULL; - queue->last = NULL; - queue->num_buffers = 0; + queue->first = NULL; + queue->last = NULL; + queue->num_buffers = 0; + queue->num_buffers_max = 0; + queue->locked_for_read = 0; pthread_mutex_init (&queue->mutex, NULL); pthread_cond_init (&queue->not_empty, NULL); @@ -171,6 +179,8 @@ static void vo_append_to_img_buf_queue_int (img_buf_fifo_t *queue, } queue->num_buffers++; + if (queue->num_buffers_max < queue->num_buffers) + queue->num_buffers_max = queue->num_buffers; pthread_cond_signal (&queue->not_empty); } @@ -211,14 +221,15 @@ static vo_frame_t *vo_remove_from_img_buf_queue_int (img_buf_fifo_t *queue, int if( width && height ) { if( !img ) { - if( queue->num_buffers == 1 && !blocking) { + if( queue->num_buffers == 1 && !blocking && queue->num_buffers_max > 8) { /* non-blocking and only a single frame on fifo with different * format -> ignore it (give another chance of a frame format hit) + * only if we have a lot of buffers at all. */ lprintf("frame format mismatch - will wait another frame\n"); } else { - /* we have at least 2 frames on fifo but they don't match -> - * give up. return whatever we got. + /* we have just a limited number of buffers or at least 2 frames + * on fifo but they don't match -> give up. return whatever we got. */ img = queue->first; lprintf("frame format miss (%d/%d)\n", i, queue->num_buffers); @@ -465,28 +476,46 @@ static int vo_frame_draw (vo_frame_t *img, xine_stream_t *stream) { duration = img->duration; /* Frame dropping slow start: - * The engine starts to drop frames if there is less than frame_drop_limit + * The engine starts to drop frames if there are less than frame_drop_limit * frames in advance. There might be a problem just after a seek because * there is no frame in advance yet. * The following code increases progressively the frame_drop_limit (-2 -> 3) * after a seek to give a chance to the engine to display the first frames - * smootly before starting to drop frames if the decoder is really too + * smoothly before starting to drop frames if the decoder is really too * slow. + * The above numbers are the result of frame_drop_limit_max beeing 3. They + * will be (-4 -> 1) when frame_drop_limit_max is only 1. This maximum value + * depends on the number of video buffers which the output device provides. */ if (stream && stream->first_frame_flag == 2) this->frame_drop_cpt = 10; if (this->frame_drop_cpt) { - this->frame_drop_limit = 3 - (this->frame_drop_cpt / 2); + this->frame_drop_limit = this->frame_drop_limit_max - (this->frame_drop_cpt / 2); this->frame_drop_cpt--; } frames_to_skip = ((-1 * diff) / duration + this->frame_drop_limit) * 2; /* do not skip decoding until output fifo frames are consumed */ - if (this->display_img_buf_queue->num_buffers > this->frame_drop_limit || + if (this->display_img_buf_queue->num_buffers >= this->frame_drop_limit || frames_to_skip < 0) frames_to_skip = 0; + /* Do not drop frames immediately, but remember this as suggestion and give + * decoder a further chance to supply frames. + * This avoids unnecessary frame drops in situations where there is only + * a very little number of image buffers, e. g. when using xxmc. + */ + if (this->frame_drop_suggested && frames_to_skip == 0) + this->frame_drop_suggested = 0; + + if (frames_to_skip > 0) { + if (!this->frame_drop_suggested) { + this->frame_drop_suggested = 1; + frames_to_skip = 0; + } + } + lprintf ("delivery diff : %" PRId64 ", current vpts is %" PRId64 ", %d frames to skip\n", diff, cur_vpts, frames_to_skip); @@ -1041,6 +1070,32 @@ static void check_redraw_needed (vos_t *this, int64_t vpts) { this->redraw_needed = 1; } +static int interruptable_sleep(vos_t *this, int usec_to_sleep) +{ + int timedout = 0; + + struct timeval now; + gettimeofday(&now, 0); + + pthread_mutex_lock (&this->trigger_drawing_mutex); + if (!this->trigger_drawing) { + struct timespec abstime; + abstime.tv_sec = now.tv_sec + usec_to_sleep / 1000000; + abstime.tv_nsec = now.tv_usec * 1000 + (usec_to_sleep % 1000000) * 1000; + + if (abstime.tv_nsec > 1000000000) { + abstime.tv_nsec -= 1000000000; + abstime.tv_sec++; + } + + timedout = pthread_cond_timedwait(&this->trigger_drawing_cond, &this->trigger_drawing_mutex, &abstime); + } + this->trigger_drawing = 0; + pthread_mutex_unlock (&this->trigger_drawing_mutex); + + return timedout; +} + /* special loop for paused mode * needed to update screen due overlay changes, resize, window * movement, brightness adjusting etc. @@ -1086,7 +1141,7 @@ static void paused_loop( vos_t *this, int64_t vpts ) } pthread_mutex_unlock( &this->free_img_buf_queue->mutex ); - xine_usec_sleep (20000); + interruptable_sleep(this, 20000); pthread_mutex_lock( &this->free_img_buf_queue->mutex ); } @@ -1216,7 +1271,10 @@ static void *video_out_loop (void *this_gen) { "video_out: vpts/clock error, next_vpts=%" PRId64 " cur_vpts=%" PRId64 "\n", next_frame_vpts,vpts); if (usec_to_sleep > 0) - xine_usec_sleep (usec_to_sleep); + { + if (0 == interruptable_sleep(this, usec_to_sleep)) + break; + } if (this->discard_frames) break; @@ -1599,6 +1657,9 @@ static void vo_exit (xine_video_port_t *this_gen) { free (this->free_img_buf_queue); free (this->display_img_buf_queue); + pthread_cond_destroy(&this->trigger_drawing_cond); + pthread_mutex_destroy(&this->trigger_drawing_mutex); + free (this); } @@ -1668,6 +1729,15 @@ static void vo_flush (xine_video_port_t *this_gen) { } } +static void vo_trigger_drawing (xine_video_port_t *this_gen) { + vos_t *this = (vos_t *) this_gen; + + pthread_mutex_lock (&this->trigger_drawing_mutex); + this->trigger_drawing = 1; + pthread_cond_signal (&this->trigger_drawing_cond); + pthread_mutex_unlock (&this->trigger_drawing_mutex); +} + /* crop_frame() will allocate a new frame to copy in the given image * while cropping. maybe someday this will be an automatic post plugin. */ @@ -1763,6 +1833,7 @@ xine_video_port_t *_x_vo_new_port (xine_t *xine, vo_driver_t *driver, int grabon this->vo.enable_ovl = vo_enable_overlay; this->vo.get_overlay_manager = vo_get_overlay_manager; this->vo.flush = vo_flush; + this->vo.trigger_drawing = vo_trigger_drawing; this->vo.get_property = vo_get_property; this->vo.set_property = vo_set_property; this->vo.status = vo_status; @@ -1782,8 +1853,6 @@ xine_video_port_t *_x_vo_new_port (xine_t *xine, vo_driver_t *driver, int grabon this->overlay_source->init (this->overlay_source); this->overlay_enabled = 1; - this->frame_drop_limit = 3; - this->frame_drop_cpt = 0; /* default number of video frames from config */ num_frame_buffers = xine->config->register_num (xine->config, @@ -1804,6 +1873,24 @@ xine_video_port_t *_x_vo_new_port (xine_t *xine, vo_driver_t *driver, int grabon if (num_frame_buffers<5) num_frame_buffers = 5; + /* Choose a frame_drop_limit which matches num_frame_buffers. + * xxmc for example supplies only 8 buffers. 2 are occupied by + * MPEG2 decoding, further 2 for displaying and the remaining 4 can + * hardly be filled all the time. + * The below constants reserve buffers for decoding, displaying and + * buffer fluctuation. + * A frame_drop_limit_max below 1 will disable frame drops at all. + */ + this->frame_drop_limit_max = num_frame_buffers - 2 - 2 - 1; + if (this->frame_drop_limit_max < 1) + this->frame_drop_limit_max = 1; + else if (this->frame_drop_limit_max > 3) + this->frame_drop_limit_max = 3; + + this->frame_drop_limit = this->frame_drop_limit_max; + this->frame_drop_cpt = 0; + this->frame_drop_suggested = 0; + this->extra_info_base = calloc (num_frame_buffers, sizeof(extra_info_t)); @@ -1840,6 +1927,9 @@ xine_video_port_t *_x_vo_new_port (xine_t *xine, vo_driver_t *driver, int grabon "were not scheduled for display in time, xine sends a notification."), 20, NULL, NULL); + pthread_mutex_init(&this->trigger_drawing_mutex, NULL); + pthread_cond_init(&this->trigger_drawing_cond, NULL); + this->trigger_drawing = 0; if (grabonly) { diff --git a/src/xine-engine/video_out.h b/src/xine-engine/video_out.h index 308e809f1..db99334eb 100644 --- a/src/xine-engine/video_out.h +++ b/src/xine-engine/video_out.h @@ -127,6 +127,9 @@ struct vo_frame_s { /* cropping to be done */ int crop_left, crop_right, crop_top, crop_bottom; + int lock_counter; + pthread_mutex_t mutex; /* protect access to lock_count */ + /* extra info coming from input or demuxers */ extra_info_t *extra_info; @@ -155,8 +158,6 @@ struct vo_frame_s { * obs: changing anything here will require recompiling vo drivers */ struct vo_frame_s *next; - int lock_counter; - pthread_mutex_t mutex; /* protect access to lock_count */ int id; /* debugging - track this frame */ int is_first; @@ -202,6 +203,9 @@ struct xine_video_port_s { /* flush video_out fifo */ void (*flush) (xine_video_port_t *self); + /* trigger immediate drawing */ + void (*trigger_drawing) (xine_video_port_t *self); + /* Get/Set video property * * See VO_PROP_* bellow @@ -440,11 +444,12 @@ struct video_overlay_manager_s { vo_driver_t *output, vo_frame_t *vo_img, int enabled); }; -/* - * build a video_out_port from - * a given video driver +/** + * @brief Build a video output port from a given video driver. + * + * @internal */ -xine_video_port_t *_x_vo_new_port (xine_t *xine, vo_driver_t *driver, int grabonly) XINE_PROTECTED; +xine_video_port_t *_x_vo_new_port (xine_t *xine, vo_driver_t *driver, int grabonly); #ifdef __cplusplus } diff --git a/src/xine-engine/video_overlay.h b/src/xine-engine/video_overlay.h index d580a1e83..6bb529204 100644 --- a/src/xine-engine/video_overlay.h +++ b/src/xine-engine/video_overlay.h @@ -35,7 +35,7 @@ #define MAX_OBJECTS 50 #define MAX_EVENTS 50 -#define MAX_SHOWING 16 +#define MAX_SHOWING (5 + 16) #define OVERLAY_EVENT_NULL 0 #define OVERLAY_EVENT_SHOW 1 @@ -43,58 +43,23 @@ #define OVERLAY_EVENT_MENU_BUTTON 3 #define OVERLAY_EVENT_FREE_HANDLE 8 /* Frees a handle, previous allocated via get_handle */ -/* number of colors in the overlay palette. Currently limited to 256 - at most, because some alphablend functions use an 8-bit index into - the palette. This should probably be classified as a bug. */ -/* FIXME: Also defines in video_out.h */ -#define OVL_PALETTE_SIZE 256 - -typedef struct vo_buttons_s { - int32_t type; /* 0:Button not valid, - 1:Button Valid, no auto_action, - 2:Button Valid, auto_action. - */ - - /* The following clipping coordinates are relative to the left upper corner - * of the OVERLAY, not of the target FRAME. Please do not mix them up! */ - int32_t hili_top; - int32_t hili_bottom; - int32_t hili_left; - int32_t hili_right; - int32_t up; - int32_t down; - int32_t left; - int32_t right; - uint32_t select_color[OVL_PALETTE_SIZE]; - uint8_t select_trans[OVL_PALETTE_SIZE]; - xine_event_t select_event; - uint32_t active_color[OVL_PALETTE_SIZE]; - uint8_t active_trans[OVL_PALETTE_SIZE]; - xine_event_t active_event; - int32_t hili_rgb_clut; /* true if clut was converted to rgb*/ - /* FIXME: Probably not needed ^^^ */ -} vo_buttons_t; - typedef struct video_overlay_object_s { int32_t handle; /* Used to match Show and Hide events. */ uint32_t object_type; /* 0=Subtitle, 1=Menu */ int64_t pts; /* Needed for Menu button compares */ vo_overlay_t *overlay; /* The image data. */ - uint32_t palette_type; /* 1 Y'CrCB, 2 R'G'B' */ uint32_t *palette; /* If NULL, no palette contained in this event. */ - int32_t buttonN; /* Current highlighed button. 0 means no info on which button to higlight */ - /* -1 means don't use this button info. */ - vo_buttons_t button[32]; /* Info regarding each button on the overlay */ + uint32_t palette_type; /* 1 Y'CrCB, 2 R'G'B' */ } video_overlay_object_t; /* This will hold all details of an event item, needed for event queue to function */ typedef struct video_overlay_event_s { - uint32_t event_type; /* Show SPU, Show OSD, Hide etc. */ int64_t vpts; /* Time when event will action. 0 means action now */ /* Once video_out blend_yuv etc. can take rle_elem_t with Colour, blend and length information. * we can remove clut and blend from this structure. * This will allow for many more colours for OSD. */ + uint32_t event_type; /* Show SPU, Show OSD, Hide etc. */ video_overlay_object_t object; /* The image data. */ } video_overlay_event_t; diff --git a/src/xine-engine/vo_scale.h b/src/xine-engine/vo_scale.h index 829405162..e502b2f62 100644 --- a/src/xine-engine/vo_scale.h +++ b/src/xine-engine/vo_scale.h @@ -98,6 +98,9 @@ struct vo_scale_s { int gui_width, gui_height; int gui_win_x, gui_win_y; + /* */ + int force_redraw; + /* * video + display pixel aspect * One pixel of height 1 has this width @@ -119,10 +122,6 @@ struct vo_scale_s { int output_yoffset; - /* */ - int force_redraw; - - /* gui callbacks */ void *user_data; diff --git a/src/xine-engine/xine.c b/src/xine-engine/xine.c index 301521e9b..83137fb82 100644 --- a/src/xine-engine/xine.c +++ b/src/xine-engine/xine.c @@ -45,6 +45,8 @@ #include <locale.h> #endif +#include <basedir.h> + #define LOG_MODULE "xine" #define LOG_VERBOSE /* @@ -66,6 +68,7 @@ #include "metronom.h" #include "configfile.h" #include "osd.h" +#include "spu.h" #include "xineutils.h" #include "compat.h" @@ -292,8 +295,37 @@ static void ticket_revoke(xine_ticket_t *this, int atomic) { pthread_mutex_unlock(&this->revoke_lock); } +static int ticket_lock_port_rewiring(xine_ticket_t *this, int ms_timeout) { + + if (ms_timeout >= 0) { + struct timespec abstime; + + struct timeval now; + gettimeofday(&now, 0); + + abstime.tv_sec = now.tv_sec + ms_timeout / 1000; + abstime.tv_nsec = now.tv_usec * 1000 + (ms_timeout % 1000) * 1e6; + + if (abstime.tv_nsec > 1e9) { + abstime.tv_nsec -= 1e9; + abstime.tv_sec++; + } + + return (0 == pthread_mutex_timedlock(&this->port_rewiring_lock, &abstime)); + } + + pthread_mutex_lock(&this->port_rewiring_lock); + return 1; +} + +static void ticket_unlock_port_rewiring(xine_ticket_t *this) { + + pthread_mutex_unlock(&this->port_rewiring_lock); +} + static void ticket_dispose(xine_ticket_t *this) { + pthread_mutex_destroy(&this->port_rewiring_lock); pthread_mutex_destroy(&this->lock); pthread_mutex_destroy(&this->revoke_lock); pthread_cond_destroy(&this->issued); @@ -314,12 +346,15 @@ static xine_ticket_t *ticket_init(void) { port_ticket->renew = ticket_renew; port_ticket->issue = ticket_issue; port_ticket->revoke = ticket_revoke; + port_ticket->lock_port_rewiring = ticket_lock_port_rewiring; + port_ticket->unlock_port_rewiring = ticket_unlock_port_rewiring; port_ticket->dispose = ticket_dispose; port_ticket->holder_thread_count = XINE_MAX_TICKET_HOLDER_THREADS; port_ticket->holder_threads = calloc(XINE_MAX_TICKET_HOLDER_THREADS,sizeof(*port_ticket->holder_threads)); pthread_mutex_init(&port_ticket->lock, NULL); pthread_mutex_init(&port_ticket->revoke_lock, NULL); + pthread_mutex_init(&port_ticket->port_rewiring_lock, NULL); pthread_cond_init(&port_ticket->issued, NULL); pthread_cond_init(&port_ticket->revoked, NULL); @@ -513,6 +548,7 @@ static int stream_rewire_audio(xine_post_out_t *output, void *data) if (!data) return 0; + stream->xine->port_ticket->lock_port_rewiring(stream->xine->port_ticket, -1); stream->xine->port_ticket->revoke(stream->xine->port_ticket, 1); if (stream->audio_out->status(stream->audio_out, stream, &bits, &rate, &mode)) { @@ -523,6 +559,7 @@ static int stream_rewire_audio(xine_post_out_t *output, void *data) stream->audio_out = new_port; stream->xine->port_ticket->issue(stream->xine->port_ticket, 1); + stream->xine->port_ticket->unlock_port_rewiring(stream->xine->port_ticket); return 1; } @@ -537,6 +574,7 @@ static int stream_rewire_video(xine_post_out_t *output, void *data) if (!data) return 0; + stream->xine->port_ticket->lock_port_rewiring(stream->xine->port_ticket, -1); stream->xine->port_ticket->revoke(stream->xine->port_ticket, 1); if (stream->video_out->status(stream->video_out, stream, &width, &height, &img_duration)) { @@ -547,6 +585,7 @@ static int stream_rewire_video(xine_post_out_t *output, void *data) stream->video_out = new_port; stream->xine->port_ticket->issue(stream->xine->port_ticket, 1); + stream->xine->port_ticket->unlock_port_rewiring(stream->xine->port_ticket); return 1; } @@ -690,9 +729,10 @@ xine_stream_t *xine_stream_new (xine_t *this, /* * osd */ - if (vo) + if (vo) { + _x_spu_misc_init (this); stream->osd_renderer = _x_osd_renderer_init(stream); - else + } else stream->osd_renderer = NULL; /* @@ -1494,6 +1534,8 @@ void xine_exit (xine_t *this) { WSACleanup(); #endif + xdgFreeHandle(this->basedir_handle); + free (this); } @@ -1619,8 +1661,11 @@ static void config_save_cb (void *this_gen, xine_cfg_entry_t *entry) { } void xine_init (xine_t *this) { - static const char *demux_strategies[] = {"default", "reverse", "content", - "extension", NULL}; + static const char *const demux_strategies[] = {"default", "reverse", "content", + "extension", NULL}; + + /* First of all, initialise libxdg-basedir as it's used by plugins. */ + this->basedir_handle = xdgAllocHandle(); /* initialize color conversion tables and functions */ init_yuv_conversion(); @@ -2053,6 +2098,9 @@ const char *const *xine_get_log_names (xine_t *this) { static inline void check_log_alloc (xine_t *this, int buf) { + if ( this->log_buffers[buf] ) + return; + pthread_mutex_lock (&this->log_lock); if ( ! this->log_buffers[buf] ) @@ -2152,3 +2200,83 @@ int _x_query_buffer_usage(xine_stream_t *stream, int *num_video_buffers, int *nu return ticket_acquired != 0; } + +int _x_lock_port_rewiring(xine_t *xine, int ms_timeout) +{ + return xine->port_ticket->lock_port_rewiring(xine->port_ticket, ms_timeout); +} + +void _x_unlock_port_rewiring(xine_t *xine) +{ + xine->port_ticket->unlock_port_rewiring(xine->port_ticket); +} + +int _x_lock_frontend(xine_stream_t *stream, int ms_to_time_out) +{ + if (ms_to_time_out >= 0) { + struct timespec abstime; + + struct timeval now; + gettimeofday(&now, 0); + + abstime.tv_sec = now.tv_sec + ms_to_time_out / 1000; + abstime.tv_nsec = now.tv_usec * 1000 + (ms_to_time_out % 1000) * 1e6; + + if (abstime.tv_nsec > 1e9) { + abstime.tv_nsec -= 1e9; + abstime.tv_sec++; + } + + return (0 == pthread_mutex_timedlock(&stream->frontend_lock, &abstime)); + } + + pthread_mutex_lock(&stream->frontend_lock); + return 1; +} + +void _x_unlock_frontend(xine_stream_t *stream) +{ + pthread_mutex_unlock(&stream->frontend_lock); +} + +int _x_query_unprocessed_osd_events(xine_stream_t *stream) +{ + video_overlay_manager_t *ovl; + int redraw_needed; + + if (!stream->xine->port_ticket->acquire_nonblocking(stream->xine->port_ticket, 1)) + return -1; + + ovl = stream->video_out->get_overlay_manager(stream->video_out); + redraw_needed = ovl->redraw_needed(ovl, 0); + + if (redraw_needed) + stream->video_out->trigger_drawing(stream->video_out); + + stream->xine->port_ticket->release_nonblocking(stream->xine->port_ticket, 1); + + return redraw_needed; +} + +int _x_demux_seek(xine_stream_t *stream, off_t start_pos, int start_time, int playing) +{ + if (!stream->demux_plugin) + return -1; + return stream->demux_plugin->seek(stream->demux_plugin, start_pos, start_time, playing); +} + +int _x_continue_stream_processing(xine_stream_t *stream) +{ + return stream->status != XINE_STATUS_STOP + && stream->status != XINE_STATUS_QUIT; +} + +void _x_trigger_relaxed_frame_drop_mode(xine_stream_t *stream) +{ + stream->first_frame_flag = 2; +} + +void _x_reset_relaxed_frame_drop_mode(xine_stream_t *stream) +{ + stream->first_frame_flag = 1; +} diff --git a/src/xine-engine/xine_internal.h b/src/xine-engine/xine_internal.h index 9b69f16f1..48aafa3f3 100644 --- a/src/xine-engine/xine_internal.h +++ b/src/xine-engine/xine_internal.h @@ -69,7 +69,6 @@ extern "C" { # include <xine/alphablend.h> #endif - #define XINE_MAX_EVENT_LISTENERS 50 #define XINE_MAX_EVENT_TYPES 100 #define XINE_MAX_TICKET_HOLDER_THREADS 64 @@ -101,19 +100,22 @@ struct xine_s { plugin_catalog_t *plugin_catalog; + int verbosity; + int demux_strategy; char *save_path; /* log output that may be presented to the user */ scratch_buffer_t *log_buffers[XINE_LOG_NUM]; - int verbosity; - xine_list_t *streams; pthread_mutex_t streams_lock; metronom_clock_t *clock; + /** Handle for libxdg-basedir functions. It's actually an xdgHandle. */ + void * basedir_handle; + #ifdef XINE_ENGINE_INTERNAL xine_ticket_t *port_ticket; pthread_mutex_t log_lock; @@ -166,6 +168,9 @@ struct xine_ticket_s { * be used in combination with acquire_nonblocking() */ void (*release_nonblocking)(xine_ticket_t *self, int irrevocable); + int (*lock_port_rewiring)(xine_ticket_t *self, int ms_timeout); + void (*unlock_port_rewiring)(xine_ticket_t *self); + void (*dispose)(xine_ticket_t *self); pthread_mutex_t lock; @@ -177,6 +182,7 @@ struct xine_ticket_s { int pending_revocations; int atomic_revoke; pthread_t atomic_revoker_thread; + pthread_mutex_t port_rewiring_lock; struct { int count; pthread_t holder; @@ -196,9 +202,9 @@ struct xine_event_queue_s { pthread_cond_t events_processed; xine_stream_t *stream; pthread_t *listener_thread; + void *user_data; xine_event_listener_cb_t callback; int callback_running; - void *user_data; }; /* @@ -216,9 +222,6 @@ struct xine_stream_s { /* demuxers use input_plugin to read data */ input_plugin_t *input_plugin; - /* current content detection method, see METHOD_BY_xxx */ - int content_detection_method; - /* used by video decoders */ xine_video_port_t *video_out; @@ -252,6 +255,9 @@ struct xine_stream_s { int spu_channel_letterbox; int spu_channel; + /* current content detection method, see METHOD_BY_xxx */ + int content_detection_method; + #ifdef XINE_ENGINE_INTERNAL /* these are private variables, plugins must not access them */ @@ -259,27 +265,38 @@ struct xine_stream_s { /* lock controlling speed change access */ pthread_mutex_t speed_change_lock; - int ignore_speed_change; /* speed changes during stop can be disastrous */ + uint32_t ignore_speed_change:1; /*< speed changes during stop can be disastrous */ + uint32_t video_thread_created:1; + uint32_t audio_thread_created:1; + uint32_t first_frame_flag:2; + uint32_t demux_action_pending:1; + uint32_t demux_thread_created:1; + uint32_t demux_thread_running:1; + uint32_t slave_is_subtitle:1; /*< ... and will be automaticaly disposed */ + uint32_t emergency_brake:1; /*< something went really wrong and this stream must be + * stopped. usually due some fatal error on output + * layers as they cannot call xine_stop. */ + uint32_t early_finish_event:1; /*< do not wait fifos get empty before sending event */ + uint32_t gapless_switch:1; /*< next stream switch will be gapless */ input_class_t *eject_class; demux_plugin_t *demux_plugin; /* vo_driver_t *video_driver;*/ pthread_t video_thread; - int video_thread_created; video_decoder_t *video_decoder_plugin; - int video_decoder_streamtype; extra_info_t *video_decoder_extra_info; + int video_decoder_streamtype; int video_channel; + uint32_t audio_track_map[50]; + int audio_track_map_entries; + + int audio_decoder_streamtype; pthread_t audio_thread; - int audio_thread_created; audio_decoder_t *audio_decoder_plugin; - int audio_decoder_streamtype; extra_info_t *audio_decoder_extra_info; - uint32_t audio_track_map[50]; - int audio_track_map_entries; uint32_t audio_type; /* *_user: -2 => off -1 => auto (use *_auto value) @@ -311,7 +328,6 @@ struct xine_stream_s { char *meta_info[XINE_STREAM_INFO_MAX]; /* seeking slowdown */ - int first_frame_flag; pthread_mutex_t first_frame_lock; pthread_cond_t first_frame_reached; @@ -329,34 +345,25 @@ struct xine_stream_s { /* demux thread stuff */ pthread_t demux_thread; - int demux_thread_created; - int demux_thread_running; pthread_mutex_t demux_lock; - int demux_action_pending; pthread_mutex_t demux_mutex; /* used in _x_demux_... functions to synchronize order of pairwise A/V buffer operations */ extra_info_t *current_extra_info; pthread_mutex_t current_extra_info_lock; int video_seek_count; - xine_post_out_t video_source; - xine_post_out_t audio_source; - - int slave_is_subtitle; /* ... and will be automaticaly disposed */ + int delay_finish_event; /* delay event in 1/10 sec units. 0=>no delay, -1=>forever */ + int slave_affection; /* what operations need to be propagated down to the slave? */ int err; + xine_post_out_t video_source; + xine_post_out_t audio_source; + broadcaster_t *broadcaster; refcounter_t *refcounter; - - int emergency_brake; /* something went really wrong and this stream must be - * stopped. usually due some fatal error on output - * layers as they cannot call xine_stop. */ - int early_finish_event; /* do not wait fifos get empty before sending event */ - int gapless_switch; /* next stream switch will be gapless */ - int delay_finish_event; /* delay event in 1/10 sec units. 0=>no delay, -1=>forever */ #endif }; @@ -370,6 +377,15 @@ struct xine_stream_s { */ int _x_query_buffer_usage(xine_stream_t *stream, int *num_video_buffers, int *num_audio_buffers, int *num_video_frames, int *num_audio_frames) XINE_PROTECTED; +int _x_lock_port_rewiring(xine_t *xine, int ms_to_time_out) XINE_PROTECTED; +void _x_unlock_port_rewiring(xine_t *xine) XINE_PROTECTED; +int _x_lock_frontend(xine_stream_t *stream, int ms_to_time_out) XINE_PROTECTED; +void _x_unlock_frontend(xine_stream_t *stream) XINE_PROTECTED; +int _x_query_unprocessed_osd_events(xine_stream_t *stream) XINE_PROTECTED; +int _x_demux_seek(xine_stream_t *stream, off_t start_pos, int start_time, int playing) XINE_PROTECTED; +int _x_continue_stream_processing(xine_stream_t *stream) XINE_PROTECTED; +void _x_trigger_relaxed_frame_drop_mode(xine_stream_t *stream) XINE_PROTECTED; +void _x_reset_relaxed_frame_drop_mode(xine_stream_t *stream) XINE_PROTECTED; void _x_handle_stream_end (xine_stream_t *stream, int non_user) XINE_PROTECTED; |