diff options
Diffstat (limited to 'src/xine-engine')
57 files changed, 1739 insertions, 5987 deletions
diff --git a/src/xine-engine/Makefile.am b/src/xine-engine/Makefile.am index ecd1968f2..2942d3560 100644 --- a/src/xine-engine/Makefile.am +++ b/src/xine-engine/Makefile.am @@ -1,47 +1,43 @@ 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 + +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 \ - xine_interface.c post.c tvmode.c broadcaster.c io_helper.c \ + video_overlay.c osd.c spu.c scratch.c demux.c vo_scale.c \ + xine_interface.c post.c broadcaster.c io_helper.c \ input_rip.c input_cache.c info_helper.c refcounter.c \ - alphablend.c + alphablend.c \ + load_plugins.h -# 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) $(LIBICONV) $(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) + -lm $(XINEUTILS_LIB) $(LTLIBICONV) $(FT2_LIBS) $(FONTCONFIG_LIBS) \ + $(LIBXINEPOSIX) $(RT_LIBS) $(NET_LIBS) $(XDG_BASEDIR_LIBS) +libxine_la_LDFLAGS = $(AM_LDFLAGS) $(def_ldflags) $(GCSECTIONS) \ + -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 +46,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 46cbfba22..993f914bf 100644 --- a/src/xine-engine/accel_xvmc.h +++ b/src/xine-engine/accel_xvmc.h @@ -16,9 +16,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - * - * $Id: accel_xvmc.h,v 1.3 2005/05/06 07:42:21 totte67 Exp $ + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * * Common acceleration definitions for XvMC. @@ -67,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], @@ -76,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 { /* @@ -110,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 9947da365..41715decb 100644 --- a/src/xine-engine/alphablend.c +++ b/src/xine-engine/alphablend.c @@ -17,7 +17,7 @@ * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA. * *------------------------------------------------------------ * @@ -32,9 +32,9 @@ #include <stdlib.h> #include <stdio.h> -#include "xine_internal.h" -#include "video_out.h" -#include "alphablend.h" +#include <xine/xine_internal.h> +#include <xine/video_out.h> +#include <xine/alphablend.h> #include "bswap.h" @@ -1052,8 +1052,7 @@ static void mem_blend8(uint8_t *mem, uint8_t val, uint8_t o, size_t sz) } } -static void blend_yuv_exact(uint8_t *dst_cr, uint8_t *dst_cb, - int src_width, int x_odd, +static void blend_yuv_exact(uint8_t *dst_cr, uint8_t *dst_cb, int src_width, uint8_t *(*blend_yuv_data)[ 3 ][ 2 ]) { int x; @@ -1062,46 +1061,38 @@ static void blend_yuv_exact(uint8_t *dst_cr, uint8_t *dst_cb, /* get opacity of the 4 pixels that share chroma */ int o00 = (*blend_yuv_data)[ 0 ][ 0 ][ x + 0 ]; int o01 = (*blend_yuv_data)[ 0 ][ 0 ][ x + 1 ]; + int o = o00 + o01; int o10 = (*blend_yuv_data)[ 0 ][ 1 ][ x + 0 ]; + o += o10; int o11 = (*blend_yuv_data)[ 0 ][ 1 ][ x + 1 ]; + o += o11; /* are there any pixels a little bit opaque? */ - if (o00 || o01 || o10 || o11) { + if (o) { /* get the chroma components of the 4 pixels */ - int cr00 = -128 + (*blend_yuv_data)[ 1 ][ 0 ][ x + 0 ]; - int cr01 = -128 + (*blend_yuv_data)[ 1 ][ 0 ][ x + 1 ]; - int cr10 = -128 + (*blend_yuv_data)[ 1 ][ 1 ][ x + 0 ]; - int cr11 = -128 + (*blend_yuv_data)[ 1 ][ 1 ][ x + 1 ]; + int cr00 = (*blend_yuv_data)[ 1 ][ 0 ][ x + 0 ]; + int cr01 = (*blend_yuv_data)[ 1 ][ 0 ][ x + 1 ]; + int cr10 = (*blend_yuv_data)[ 1 ][ 1 ][ x + 0 ]; + int cr11 = (*blend_yuv_data)[ 1 ][ 1 ][ x + 1 ]; - int cb00 = -128 + (*blend_yuv_data)[ 2 ][ 0 ][ x + 0 ]; - int cb01 = -128 + (*blend_yuv_data)[ 2 ][ 0 ][ x + 1 ]; - int cb10 = -128 + (*blend_yuv_data)[ 2 ][ 1 ][ x + 0 ]; - int cb11 = -128 + (*blend_yuv_data)[ 2 ][ 1 ][ x + 1 ]; + int cb00 = (*blend_yuv_data)[ 2 ][ 0 ][ x + 0 ]; + int cb01 = (*blend_yuv_data)[ 2 ][ 0 ][ x + 1 ]; + int cb10 = (*blend_yuv_data)[ 2 ][ 1 ][ x + 0 ]; + int cb11 = (*blend_yuv_data)[ 2 ][ 1 ][ x + 1 ]; /* are all pixels completely opaque? */ - if (o00 >= 0xf && o01 >= 0xf && o10 >= 0xf && o11 >= 0xf) { + if (o >= 4*0xf) { /* set the output chroma to the average of the four pixels */ - *dst_cr = 128 + (cr00 + cr01 + cr10 + cr11) / 4; - *dst_cb = 128 + (cb00 + cb01 + cb10 + cb11) / 4; + *dst_cr = (cr00 + cr01 + cr10 + cr11) / 4; + *dst_cb = (cb00 + cb01 + cb10 + cb11) / 4; } else { - int t4, cr, cb; - - /* blending required, so clamp opacity values to allowed range */ - if (o00 > 0xf) o00 = 0xf; - if (o01 > 0xf) o01 = 0xf; - if (o10 > 0xf) o10 = 0xf; - if (o11 > 0xf) o11 = 0xf; - /* calculate transparency of background over the four pixels */ - t4 = (0xf - o00) + (0xf - o01) + (0xf - o10) + (0xf - o11); - - /* get background chroma */ - cr = -128 + *dst_cr; - cb = -128 + *dst_cb; + int t4 = 4*0xf - o; /* blend the output chroma to the average of the four pixels */ - *dst_cr = 128 + (cr * t4 + cr00 * o00 + cr01 * o01 + cr10 * o10 + cr11 * o11) / (4 * 0xf); - *dst_cb = 128 + (cb * t4 + cb00 * o00 + cb01 * o01 + cb10 * o10 + cb11 * o11) / (4 * 0xf); + /* for explanation of the used equation, see blend_yuy2_exact() */ + *dst_cr = ((*dst_cr * t4 + cr00 * o00 + cr01 * o01 + cr10 * o10 + cr11 * o11) * (0x1111+1)) >> 18; + *dst_cb = ((*dst_cb * t4 + cb00 * o00 + cb01 * o01 + cb10 * o10 + cb11 * o11) * (0x1111+1)) >> 18; } } @@ -1113,7 +1104,7 @@ static void blend_yuv_exact(uint8_t *dst_cr, uint8_t *dst_cb, 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 ]; @@ -1440,7 +1431,7 @@ void _x_blend_yuv (uint8_t *dst_base[3], vo_overlay_t * img_overl, memset(&(*blend_yuv_data)[ 0 ][ 1 ][ 0 ], 0, exact_blend_width_m2); } - blend_yuv_exact(dst_cr, dst_cb, exact_blend_width, x_odd, blend_yuv_data); + blend_yuv_exact(dst_cr, dst_cb, exact_blend_width, blend_yuv_data); any_line_buffered = 0; } @@ -1461,7 +1452,7 @@ void _x_blend_yuv (uint8_t *dst_base[3], vo_overlay_t * img_overl, memset(&(*blend_yuv_data)[ 0 ][ 1 ][ 0 ], 0, exact_blend_width_m2); } - blend_yuv_exact(dst_cr, dst_cb, exact_blend_width, x_odd, blend_yuv_data); + blend_yuv_exact(dst_cr, dst_cb, exact_blend_width, blend_yuv_data); } } @@ -1470,8 +1461,7 @@ void _x_blend_yuv (uint8_t *dst_base[3], vo_overlay_t * img_overl, #endif } -static void blend_yuy2_exact(uint8_t *dst_cr, uint8_t *dst_cb, - int src_width, int x_odd, +static void blend_yuy2_exact(uint8_t *dst_cr, uint8_t *dst_cb, int src_width, uint8_t *(*blend_yuy2_data)[ 3 ]) { int x; @@ -1480,38 +1470,71 @@ static void blend_yuy2_exact(uint8_t *dst_cr, uint8_t *dst_cb, /* get opacity of the 2 pixels that share chroma */ int o0 = (*blend_yuy2_data)[ 0 ][ x + 0 ]; int o1 = (*blend_yuy2_data)[ 0 ][ x + 1 ]; + int o = o0 + o1; /* are there any pixels a little bit opaque? */ - if (o0 || o1) { + if (o) { /* get the chroma components of the 2 pixels */ - int cr0 = -128 + (*blend_yuy2_data)[ 1 ][ x + 0 ]; - int cr1 = -128 + (*blend_yuy2_data)[ 1 ][ x + 1 ]; + int cr0 = (*blend_yuy2_data)[ 1 ][ x + 0 ]; + int cr1 = (*blend_yuy2_data)[ 1 ][ x + 1 ]; - int cb0 = -128 + (*blend_yuy2_data)[ 2 ][ x + 0 ]; - int cb1 = -128 + (*blend_yuy2_data)[ 2 ][ x + 1 ]; + int cb0 = (*blend_yuy2_data)[ 2 ][ x + 0 ]; + int cb1 = (*blend_yuy2_data)[ 2 ][ x + 1 ]; /* are all pixels completely opaque? */ - if (o0 >= 0xf && o1 >= 0xf) { + if (o >= 2*0xf) { /* set the output chroma to the average of the two pixels */ - *dst_cr = 128 + (cr0 + cr1) / 2; - *dst_cb = 128 + (cb0 + cb1) / 2; + *dst_cr = (cr0 + cr1) / 2; + *dst_cb = (cb0 + cb1) / 2; } else { - int t2, cr, cb; - - /* blending required, so clamp opacity values to allowed range */ - if (o0 > 0xf) o0 = 0xf; - if (o1 > 0xf) o1 = 0xf; - /* calculate transparency of background over the two pixels */ - t2 = (0xf - o0) + (0xf - o1); - - /* get background chroma */ - cr = -128 + *dst_cr; - cb = -128 + *dst_cb; + int t2 = 2*0xf - o; + + /* + * No need to adjust chroma values with +/- 128: + * *dst_cb + * = 128 + ((*dst_cb-128) * t2 + (cb0-128) * o0 + (cb1-128) * o1) / (2 * 0xf); + * = 128 + (*dst_cb * t2 + cb0 * o0 + cb1 * o1 + (t2*(-128) - 128*o0 - 128*o1)) / (2 * 0xf); + * = 128 + (*dst_cb * t2 + cb0 * o0 + cb1 * o1 + ((2*0xf-o0-o1)*(-128) - 128*o0 - 128*o1)) / (2 * 0xf); + * = 128 + (*dst_cb * t2 + cb0 * o0 + cb1 * o1 + (2*0xf*(-128))) / (2 * 0xf); + * = 128 + (*dst_cb * t2 + cb0 * o0 + cb1 * o1) / (2 * 0xf) - 128; + * = (*dst_cb * t2 + cb0 * o0 + cb1 * o1) / (2 * 0xf); + * + * Convert slow divisions to multiplication and shift: + * X/0xf + * = X * (1/0xf) + * = X * (0x1111/0x1111) * (1/0xf) + * = X * 0x1111/0xffff + * =(almost) X * 0x1112/0x10000 + * = (X * 0x1112) >> 16 + * + * The tricky point is 0x1111/0xffff --> 0x1112/0x10000. + * All calculations are done using integers and X is in + * range of [0 ... 0xff*0xf*4]. This results in error of + * X*0x1112/0x10000 - X/0xf + * = X*(0x1112/0x10000 - 1/0xf) + * = X*(0x0.1112 - 0x0.111111...) + * = X*0.0000eeeeee.... + * = [0 ... 0.37c803fc...] when X in [0...3bc4] + * As the error is less than 1 and always positive, whole error + * "disappears" during truncation (>>16). Rounding to exact results is + * guaranteed by selecting 0x1112 instead of more accurate 0x1111 + * (with 0x1111 error=X*(-0.00001111...)). With 0x1112 error is + * always positive, but still less than one. + * So, one can forget the "=(almost)" as it is really "=" when source + * operands are within 0...0xff (U,V) and 0...0xf (A). + * + * 1/0x10000 (= >>16) was originally selected because of MMX pmullhw + * instruction; it makes possible to do whole calculation in MMX using + * uint16's (pmullhw is (X*Y)>>16). + * + * Here X/(2*0xf) = X/0xf/2 = ((X*0x1112)>>16)>>1 = (X*0x1112)>>17 + */ /* blend the output chroma to the average of the two pixels */ - *dst_cr = 128 + (cr * t2 + cr0 * o0 + cr1 * o1) / (2 * 0xf); - *dst_cb = 128 + (cb * t2 + cb0 * o0 + cb1 * o1) / (2 * 0xf); + /* *dst_cr = 128 + ((*dst_cr-128) * t2 + (cr0-128) * o0 + (cr1-128) * o1) / (2 * 0xf); */ + *dst_cr = ((*dst_cr * t2 + cr0 * o0 + cr1 * o1) * (0x1111+1)) >> 17; + *dst_cb = ((*dst_cb * t2 + cb0 * o0 + cb1 * o1) * (0x1111+1)) >> 17; } } @@ -1523,7 +1546,7 @@ static void blend_yuy2_exact(uint8_t *dst_cr, uint8_t *dst_cb, 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 ]; @@ -1855,7 +1878,7 @@ void _x_blend_yuy2 (uint8_t * dst_img, vo_overlay_t * img_overl, if (enable_exact_blending) { /* blend buffered line */ if (any_line_buffered) { - blend_yuy2_exact(dst_y - x_odd * 2 + 3, dst_y - x_odd * 2 + 1, exact_blend_width, x_odd, blend_yuy2_data); + blend_yuy2_exact(dst_y - x_odd * 2 + 3, dst_y - x_odd * 2 + 1, exact_blend_width, blend_yuy2_data); any_line_buffered = 0; } @@ -1936,7 +1959,7 @@ static int xx44_paletteIndex(xx44_palette_t *p, int color, uint32_t clut) } if (p->max_used == p->size -1) { - printf("video_out: Warning! Out of xx44 palette colors!\n"); + printf("video_out: Warning! Out of xx44 palette colours!\n"); return 1; } p->cluts[p->max_used] = clut; diff --git a/src/xine-engine/alphablend.h b/src/xine-engine/alphablend.h deleted file mode 100644 index 513ac116f..000000000 --- a/src/xine-engine/alphablend.h +++ /dev/null @@ -1,136 +0,0 @@ -/* - * - * Copyright (C) 2000 Thomas Mirlacher - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * The author may be reached as <dent@linuxvideo.org> - * - *------------------------------------------------------------ - * - */ - -#ifndef __ALPHABLEND_H__ -#define __ALPHABLEND_H__ - -#include "video_out.h" - -typedef struct { - void *buffer; - int buffer_size; - - int disable_exact_blending; - - int offset_x, offset_y; -} alphablend_t; - -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; - - -#if PRAGMA_PACK -#pragma pack() -#endif - -#define XX44_PALETTE_SIZE 32 - -typedef struct { - unsigned size; - unsigned max_used; - uint32_t cluts[XX44_PALETTE_SIZE]; - /* cache palette entries for both colors and hili_colors */ - int lookup_cache[OVL_PALETTE_SIZE*2]; -} xx44_palette_t; - - -void _x_blend_rgb16 (uint8_t * img, vo_overlay_t * img_overl, - int img_width, int img_height, - int dst_width, int dst_height, - alphablend_t *extra_data) XINE_PROTECTED; - -void _x_blend_rgb24 (uint8_t * img, vo_overlay_t * img_overl, - int img_width, int img_height, - int dst_width, int dst_height, - alphablend_t *extra_data) XINE_PROTECTED; - -void _x_blend_rgb32 (uint8_t * img, vo_overlay_t * img_overl, - int img_width, int img_height, - int dst_width, int dst_height, - alphablend_t *extra_data) XINE_PROTECTED; - -void _x_blend_yuv (uint8_t *dst_base[3], vo_overlay_t * img_overl, - int dst_width, int dst_height, int dst_pitches[3], - alphablend_t *extra_data) XINE_PROTECTED; - -void _x_blend_yuy2 (uint8_t * dst_img, vo_overlay_t * img_overl, - int dst_width, int dst_height, int dst_pitch, - alphablend_t *extra_data) XINE_PROTECTED; - -/* - * This function isn't too smart about blending. We want to avoid creating new - * colors in the palette as a result from two non-zero colors needed to be - * blended. Instead we choose the color with the highest alpha value to be - * visible. Some parts of the code taken from the "VeXP" project. - */ - -void _x_blend_xx44 (uint8_t *dst_img, vo_overlay_t *img_overl, - int dst_width, int dst_height, int dst_pitch, - alphablend_t *extra_data, - xx44_palette_t *palette,int ia44) XINE_PROTECTED; - -/* - * Functions to handle the xine-specific palette. - */ - -void _x_clear_xx44_palette(xx44_palette_t *p) XINE_PROTECTED; -void _x_init_xx44_palette(xx44_palette_t *p, unsigned num_entries) XINE_PROTECTED; -void _x_dispose_xx44_palette(xx44_palette_t *p) XINE_PROTECTED; - -/* - * Convert the xine-specific palette to something useful. - */ - -void _x_xx44_to_xvmc_palette(const xx44_palette_t *p,unsigned char *xvmc_palette, - unsigned first_xx44_entry, unsigned num_xx44_entries, - unsigned num_xvmc_components, char *xvmc_components) XINE_PROTECTED; - - -#endif diff --git a/src/xine-engine/audio_decoder.c b/src/xine-engine/audio_decoder.c index 549c19b02..6a0688f0d 100644 --- a/src/xine-engine/audio_decoder.c +++ b/src/xine-engine/audio_decoder.c @@ -15,9 +15,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - * - * $Id: audio_decoder.c,v 1.139 2007/02/20 00:34:57 dgp85 Exp $ + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * * functions that implement audio decoding @@ -41,8 +39,8 @@ #define LOG */ -#include "xine_internal.h" -#include "xineutils.h" +#include <xine/xine_internal.h> +#include <xine/xineutils.h> static void *audio_decoder_loop (void *stream_gen) { @@ -253,6 +251,7 @@ static void *audio_decoder_loop (void *stream_gen) { uint32_t audio_type = 0; int i,j; + uint32_t chan=buf->type&0x0000FFFF; /* printf("audio_decoder: buf_type=%08x auto=%08x user=%08x\n", @@ -264,11 +263,11 @@ static void *audio_decoder_loop (void *stream_gen) { /* update track map */ i = 0; - while ( (i<stream->audio_track_map_entries) && (stream->audio_track_map[i]<buf->type) ) + while ( (i<stream->audio_track_map_entries) && ((stream->audio_track_map[i]&0x0000FFFF)<chan) ) i++; if ( (i==stream->audio_track_map_entries) - || (stream->audio_track_map[i] != buf->type) ) { + || ((stream->audio_track_map[i]&0x0000FFFF)!=chan) ) { xine_event_t ui_event; j = stream->audio_track_map_entries; diff --git a/src/xine-engine/audio_decoder.h b/src/xine-engine/audio_decoder.h deleted file mode 100644 index a88b02dc8..000000000 --- a/src/xine-engine/audio_decoder.h +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (C) 2000-2004 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - * - * $Id: audio_decoder.h,v 1.13 2004/09/26 22:54:52 valtri Exp $ - * - * xine audio decoder plugin interface - * - */ - -#ifndef HAVE_AUDIO_DECODER_H -#define HAVE_AUDIO_DECODER_H - -#ifdef XINE_COMPILE -# include <inttypes.h> -# include "buffer.h" -#else -# include <xine/os_types.h> -# include <xine/buffer.h> -#endif - -#define AUDIO_DECODER_IFACE_VERSION 15 - -/* - * generic xine audio decoder plugin interface - */ - -typedef struct audio_decoder_class_s audio_decoder_class_t; -typedef struct audio_decoder_s audio_decoder_t; - -struct audio_decoder_class_s { - - /* - * open a new instance of this plugin class - */ - audio_decoder_t* (*open_plugin) (audio_decoder_class_t *this, xine_stream_t *stream); - - /* - * return short, human readable identifier for this plugin class - */ - char* (*get_identifier) (audio_decoder_class_t *this); - - /* - * return human readable (verbose = 1 line) description for - * this plugin class - */ - char* (*get_description) (audio_decoder_class_t *this); - - /* - * free all class-related resources - */ - - void (*dispose) (audio_decoder_class_t *this); -}; - - -struct audio_decoder_s { - - /* - * decode data from buf and feed decoded samples to - * audio output - */ - void (*decode_data) (audio_decoder_t *this, buf_element_t *buf); - - /* - * reset decoder after engine flush (prepare for new - * audio data not related to recently decoded data) - */ - void (*reset) (audio_decoder_t *this); - - /* - * inform decoder that a time reference discontinuity has happened. - * that is, it must forget any currently held pts value - */ - void (*discontinuity) (audio_decoder_t *this); - - /* - * close down, free all resources - */ - void (*dispose) (audio_decoder_t *this); - - void *node; /* used by plugin loader */ - -}; - -#endif diff --git a/src/xine-engine/audio_out.c b/src/xine-engine/audio_out.c index 89fbdde1a..5162c1883 100644 --- a/src/xine-engine/audio_out.c +++ b/src/xine-engine/audio_out.c @@ -15,17 +15,19 @@ * * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + */ + +/** + * @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> * - * $Id: audio_out.c,v 1.210 2007/04/01 00:52:36 dgp85 Exp $ * - * 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 - */ - -/* * General Programming Guidelines: - * New concept of an "audio_frame". * An audio_frame consists of all the samples required to fill every @@ -53,7 +55,6 @@ * Copyright (C) 2002 Felipe Rivera <liebremx at users sourceforge net> * * heavily modified by guenter bartsch 2003 for use in libxine - * */ #ifndef __sun @@ -88,11 +89,11 @@ #define LOG_RESAMPLE_SYNC 0 -#include "xine_internal.h" -#include "xineutils.h" -#include "audio_out.h" -#include "resample.h" -#include "metronom.h" +#include <xine/xine_internal.h> +#include <xine/xineutils.h> +#include <xine/audio_out.h> +#include <xine/resample.h> +#include <xine/metronom.h> #define NUM_AUDIO_BUFFERS 32 @@ -174,7 +175,7 @@ typedef struct { }sXYData; -static sIIRCoefficients iir_cf[] = { +static const sIIRCoefficients iir_cf[] = { /* 31 Hz*/ { EQ_REAL(9.9691562441e-01), EQ_REAL(1.5421877947e-03), EQ_REAL(1.9968961468e+00) }, /* 62 Hz*/ @@ -251,6 +252,7 @@ typedef struct { * sure nobody will change speed without going through xine.c:set_speed_internal */ int slow_fast_audio; /* play audio even on slow/fast speeds */ + int16_t last_sample[RESAMPLE_MAX_CHANNELS]; audio_buffer_t *frame_buf[2]; /* two buffers for "stackable" conversions */ int16_t *zero_space; @@ -289,6 +291,7 @@ struct audio_fifo_s { int num_buffers; }; +static int ao_set_property (xine_audio_port_t *this_gen, int property, int value); static audio_fifo_t *fifo_new (xine_t *xine) { @@ -339,9 +342,7 @@ static void fifo_append (audio_fifo_t *fifo, pthread_mutex_unlock (&fifo->mutex); } -static audio_buffer_t *fifo_remove_int (audio_fifo_t *fifo, int blocking) { - audio_buffer_t *buf; - +static audio_buffer_t *fifo_peek_int (audio_fifo_t *fifo, int blocking) { while (!fifo->first) { pthread_cond_signal (&fifo->empty); if (blocking) @@ -356,25 +357,38 @@ static audio_buffer_t *fifo_remove_int (audio_fifo_t *fifo, int blocking) { return NULL; } } + return fifo->first; +} - buf = fifo->first; - - if (buf) { - fifo->first = buf->next; +static audio_buffer_t *fifo_remove_int (audio_fifo_t *fifo, int blocking) { + audio_buffer_t *buf = fifo_peek_int(fifo, blocking); + if (!buf) + return NULL; - if (!fifo->first) { + fifo->first = buf->next; - fifo->last = NULL; - fifo->num_buffers = 0; - pthread_cond_signal (&fifo->empty); + if (!fifo->first) { - } else - fifo->num_buffers--; + fifo->last = NULL; + fifo->num_buffers = 0; + pthread_cond_signal (&fifo->empty); - } + } else + fifo->num_buffers--; buf->next = NULL; - + + return buf; +} + +static audio_buffer_t *fifo_peek (audio_fifo_t *fifo) { + + audio_buffer_t *buf; + + pthread_mutex_lock (&fifo->mutex); + buf = fifo_peek_int(fifo, 1); + pthread_mutex_unlock (&fifo->mutex); + return buf; } @@ -576,18 +590,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; } @@ -595,7 +607,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) { @@ -612,7 +624,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) { @@ -746,19 +758,19 @@ static audio_buffer_t* prepare_samples( aos_t *this, audio_buffer_t *buf) { switch (this->input.mode) { case AO_CAP_MODE_MONO: ensure_buffer_size(this->frame_buf[1], (this->output.bits>>3), num_output_frames); - _x_audio_out_resample_mono (buf->mem, buf->num_frames, + _x_audio_out_resample_mono (this->last_sample, buf->mem, buf->num_frames, this->frame_buf[1]->mem, num_output_frames); buf = swap_frame_buffers(this); break; case AO_CAP_MODE_STEREO: ensure_buffer_size(this->frame_buf[1], (this->output.bits>>3)*2, num_output_frames); - _x_audio_out_resample_stereo (buf->mem, buf->num_frames, + _x_audio_out_resample_stereo (this->last_sample, buf->mem, buf->num_frames, this->frame_buf[1]->mem, num_output_frames); buf = swap_frame_buffers(this); break; case AO_CAP_MODE_4CHANNEL: ensure_buffer_size(this->frame_buf[1], (this->output.bits>>3)*4, num_output_frames); - _x_audio_out_resample_4channel (buf->mem, buf->num_frames, + _x_audio_out_resample_4channel (this->last_sample, buf->mem, buf->num_frames, this->frame_buf[1]->mem, num_output_frames); buf = swap_frame_buffers(this); break; @@ -766,7 +778,7 @@ static audio_buffer_t* prepare_samples( aos_t *this, audio_buffer_t *buf) { case AO_CAP_MODE_5CHANNEL: case AO_CAP_MODE_5_1CHANNEL: ensure_buffer_size(this->frame_buf[1], (this->output.bits>>3)*6, num_output_frames); - _x_audio_out_resample_6channel (buf->mem, buf->num_frames, + _x_audio_out_resample_6channel (this->last_sample, buf->mem, buf->num_frames, this->frame_buf[1]->mem, num_output_frames); buf = swap_frame_buffers(this); break; @@ -775,6 +787,25 @@ static audio_buffer_t* prepare_samples( aos_t *this, audio_buffer_t *buf) { /* pass-through modes: no resampling */ break; } + } else { + /* maintain last_sample in case we need it */ + switch (this->input.mode) { + case AO_CAP_MODE_MONO: + memcpy (this->last_sample, &buf->mem[buf->num_frames - 1], sizeof (this->last_sample[0])); + break; + case AO_CAP_MODE_STEREO: + memcpy (this->last_sample, &buf->mem[(buf->num_frames - 1) * 2], 2 * sizeof (this->last_sample[0])); + break; + case AO_CAP_MODE_4CHANNEL: + memcpy (this->last_sample, &buf->mem[(buf->num_frames - 1) * 4], 4 * sizeof (this->last_sample[0])); + break; + case AO_CAP_MODE_4_1CHANNEL: + case AO_CAP_MODE_5CHANNEL: + case AO_CAP_MODE_5_1CHANNEL: + memcpy (this->last_sample, &buf->mem[(buf->num_frames - 1) * 6], 6 * sizeof (this->last_sample[0])); + break; + default:; + } } /* mode conversion */ @@ -980,7 +1011,7 @@ static void *ao_loop (void *this_gen) { if (!in_buf) { lprintf ("loop: get buf from fifo\n"); - in_buf = fifo_remove (this->out_fifo); + in_buf = fifo_peek (this->out_fifo); bufs_since_sync++; lprintf ("got a buffer\n"); } @@ -993,6 +1024,7 @@ static void *ao_loop (void *this_gen) { } if (this->discard_buffers) { + fifo_remove (this->out_fifo); if (in_buf->stream) _x_refcounter_dec(in_buf->stream->refcounter); fifo_append (this->free_fifo, in_buf); @@ -1019,6 +1051,7 @@ static void *ao_loop (void *this_gen) { cur_time = this->clock->get_current_time (this->clock); if (in_buf->vpts < cur_time ) { lprintf ("loop: next fifo\n"); + fifo_remove (this->out_fifo); if (in_buf->stream) _x_refcounter_dec(in_buf->stream->refcounter); fifo_append (this->free_fifo, in_buf); @@ -1143,6 +1176,7 @@ static void *ao_loop (void *this_gen) { /* drop package */ lprintf ("loop: drop package, next fifo\n"); + fifo_remove (this->out_fifo); if (in_buf->stream) _x_refcounter_dec(in_buf->stream->refcounter); fifo_append (this->free_fifo, in_buf); @@ -1209,15 +1243,30 @@ static void *ao_loop (void *this_gen) { } else { result = 0; } + fifo_remove (this->out_fifo); if( result < 0 ) { - /* FIXME: USB device unplugged. - * We should get the card into a closed state here, that involves closing - * the PCM as well as the MIXER. - * Maybe we should pause the stream until the USB device is plugged in again. - * Return values 0 happen even if usb not unplugged, so needs further investigation. - */ - xprintf(this->xine, XINE_VERBOSITY_LOG, _("write to sound card failed. Was a USB device unplugged ?\n")); + /* device unplugged. */ + xprintf(this->xine, XINE_VERBOSITY_LOG, _("write to sound card failed. Assuming the device was unplugged.\n")); + _x_message (in_buf->stream, XINE_MSG_AUDIO_OUT_UNAVAILABLE, NULL); + + pthread_mutex_lock( &this->driver_lock ); + if(this->driver_open) { + this->driver->close(this->driver); + this->driver_open = 0; + this->driver->exit(this->driver); + this->driver = _x_load_audio_output_plugin (this->xine, "none"); + if (this->driver && !in_buf->stream->emergency_brake && + ao_change_settings(this, + in_buf->format.bits, + in_buf->format.rate, + in_buf->format.mode) == 0) { + in_buf->stream->emergency_brake = 1; + _x_message (in_buf->stream, XINE_MSG_AUDIO_OUT_UNAVAILABLE, NULL); + } + } + pthread_mutex_unlock( &this->driver_lock ); + /* closing the driver will result in XINE_MSG_AUDIO_OUT_UNAVAILABLE to be emitted */ } lprintf ("loop: next buf from fifo\n"); @@ -1387,7 +1436,7 @@ static int ao_change_settings(aos_t *this, uint32_t bits, uint32_t rate, int mod _("stereo not supported by driver, converting to mono.\n")); } - output_sample_rate=this->driver->open(this->driver,bits,(this->force_rate ? this->force_rate : rate),mode); + output_sample_rate=(this->driver->open) (this->driver,bits,(this->force_rate ? this->force_rate : rate),mode); } else output_sample_rate = this->input.rate; @@ -1565,6 +1614,11 @@ static void ao_close(xine_audio_port_t *this_gen, xine_stream_t *stream) { xprintf (this->xine, XINE_VERBOSITY_DEBUG, "audio_out: no streams left, closing driver\n"); if (this->audio_loop_running) { + if (this->clock->speed == XINE_SPEED_PAUSE || + (this->clock->speed != XINE_FINE_SPEED_NORMAL && !this->slow_fast_audio)) { + /* discard buffers, otherwise we'll wait forever */ + ao_set_property(this_gen, AO_PROP_DISCARD_BUFFERS, 1); + } /* make sure there are no more buffers on queue */ fifo_wait_empty(this->out_fifo); } @@ -1991,8 +2045,8 @@ xine_audio_port_t *_x_ao_new_port (xine_t *xine, ao_driver_t *driver, int i, err; pthread_attr_t pth_attrs; pthread_mutexattr_t attr; - static const char* resample_modes[] = {"auto", "off", "on", NULL}; - static const char* av_sync_methods[] = {"metronom feedback", "resample", NULL}; + static const char *const resample_modes[] = {"auto", "off", "on", NULL}; + static const char *const av_sync_methods[] = {"metronom feedback", "resample", NULL}; this = xine_xmalloc (sizeof (aos_t)) ; @@ -2146,6 +2200,8 @@ xine_audio_port_t *_x_ao_new_port (xine_t *xine, ao_driver_t *driver, fifo_append (this->free_fifo, buf); } + + memset (this->last_sample, 0, sizeof (this->last_sample)); /* buffers used for audio conversions */ for (i=0; i<2; i++) { diff --git a/src/xine-engine/audio_out.h b/src/xine-engine/audio_out.h deleted file mode 100644 index c5f335dbb..000000000 --- a/src/xine-engine/audio_out.h +++ /dev/null @@ -1,345 +0,0 @@ -/* - * Copyright (C) 2000-2004 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - * - * $Id: audio_out.h,v 1.77 2006/09/26 05:19:48 dgp85 Exp $ - */ -#ifndef HAVE_AUDIO_OUT_H -#define HAVE_AUDIO_OUT_H - -#ifdef __cplusplus -extern "C" { -#endif - -#if defined(XINE_COMPILE) -#include <inttypes.h> -#include "metronom.h" -#include "configfile.h" -#include "xineutils.h" -#else -#include <xine/os_types.h> -#include <xine/metronom.h> -#include <xine/configfile.h> -#include <xine/xineutils.h> -#endif - - -#define AUDIO_OUT_IFACE_VERSION 8 - -/* - * ao_driver_s contains the driver every audio output - * driver plugin has to implement. - */ - -typedef struct ao_driver_s ao_driver_t; - -struct ao_driver_s { - - /* - * - * find out what output modes + capatilities are supported by - * this plugin (constants for the bit vector to return see above) - * - * See AO_CAP_* bellow. - */ - uint32_t (*get_capabilities) (ao_driver_t *); - - /* - * open the driver and make it ready to receive audio data - * buffers may be flushed(!) - * - * return value: 0 : failure, >0 : output sample rate - */ - int (*open)(ao_driver_t *, uint32_t bits, uint32_t rate, int mode); - - /* return the number of audio channels - */ - int (*num_channels)(ao_driver_t *self_gen); - - /* return the number of bytes per frame. - * A frame is equivalent to one sample being output on every audio channel. - */ - int (*bytes_per_frame)(ao_driver_t *self_gen); - - /* return the delay is frames measured by - * looking at pending samples in the audio output device - */ - int (*delay)(ao_driver_t *self_gen); - - /* - * return gap tolerance (in pts) needed for this driver - */ - int (*get_gap_tolerance) (ao_driver_t *self_gen); - - /* - * write audio data to audio output device - * return value: - * >0 => audio samples were processed ok - * 0 => audio samples were not yet processed, - * call write_audio_data with the _same_ samples again - */ - int (*write)(ao_driver_t *, - int16_t* audio_data, uint32_t num_samples); - - /* - * this is called when the decoder no longer uses the audio - * output driver - the driver should get ready to get opened() again - */ - void (*close)(ao_driver_t *); - - /* - * shut down this audio output driver plugin and - * free all resources allocated - */ - void (*exit) (ao_driver_t *); - - /* - * Get, Set a property of audio driver. - * - * get_property() return 1 in success, 0 on failure. - * set_property() return value on success, ~value on failure. - * - * See AO_PROP_* below for available properties. - */ - int (*get_property) (ao_driver_t *, int property); - - int (*set_property) (ao_driver_t *, int property, int value); - - - /* - * misc control operations on the audio device. - * - * See AO_CTRL_* below. - */ - int (*control) (ao_driver_t *, int cmd, /* arg */ ...); - - void *node; -}; - -typedef struct ao_format_s ao_format_t; - -struct ao_format_s { - uint32_t bits; - uint32_t rate; - int mode; -}; - -typedef struct audio_fifo_s audio_fifo_t; - -typedef struct audio_buffer_s audio_buffer_t; - -struct audio_buffer_s { - - audio_buffer_t *next; - - int16_t *mem; - int mem_size; - int num_frames; - - int64_t vpts; - uint32_t frame_header_count; - uint32_t first_access_unit; - - /* extra info coming from input or demuxers */ - extra_info_t *extra_info; - - xine_stream_t *stream; /* stream that send that buffer */ - - ao_format_t format; /* let each buffer carry it's own format info */ -}; - -/* - * xine_audio_port_s contains the port every audio decoder talks to - * - * Remember that adding new functions to this structure requires - * adaption of the post plugin decoration layer. Be sure to look into - * src/xine-engine/post.[ch]. - */ - -struct xine_audio_port_s { - uint32_t (*get_capabilities) (xine_audio_port_t *); /* for constants see below */ - - /* * Get/Set audio property - * - * See AO_PROP_* bellow - */ - int (*get_property) (xine_audio_port_t *, int property); - int (*set_property) (xine_audio_port_t *, int property, int value); - - /* open audio driver for audio output - * return value: 0:failure, >0:output sample rate - */ - /* when you are not a full-blown stream, but still need to open the port - * (e.g. you are a post plugin) it is legal to pass an anonymous stream */ - int (*open) (xine_audio_port_t *, xine_stream_t *stream, - uint32_t bits, uint32_t rate, int mode); - - /* - * get a piece of memory for audio data - */ - audio_buffer_t * (*get_buffer) (xine_audio_port_t *); - - /* - * append a buffer filled with audio data to the audio fifo - * for output - */ - /* when the frame does not originate from a stream, it is legal to pass an anonymous stream */ - void (*put_buffer) (xine_audio_port_t *, audio_buffer_t *buf, xine_stream_t *stream); - - /* audio driver is no longer used by decoder => close */ - /* when you are not a full-blown stream, but still need to close the port - * (e.g. you are a post plugin) it is legal to pass an anonymous stream */ - void (*close) (xine_audio_port_t *self, xine_stream_t *stream); - - /* called on xine exit */ - void (*exit) (xine_audio_port_t *); - - /* - * misc control operations on the audio device. - * - * See AO_CTRL_* below. - */ - int (*control) (xine_audio_port_t *, int cmd, /* arg */ ...); - - /* - * Flush audio_out fifo. - */ - void (*flush) (xine_audio_port_t *); - - /* - * Check if port is opened for this stream and get parameters. - * The stream can be anonymous. - */ - int (*status) (xine_audio_port_t *, xine_stream_t *stream, - uint32_t *bits, uint32_t *rate, int *mode); - -}; - -typedef struct audio_driver_class_s audio_driver_class_t; - -struct audio_driver_class_s { - - /* - * open a new instance of this plugin class - */ - ao_driver_t* (*open_plugin) (audio_driver_class_t *, const void *data); - - /* - * return short, human readable identifier for this plugin class - */ - char* (*get_identifier) (audio_driver_class_t *); - - /* - * return human readable (verbose = 1 line) description for - * this plugin class - */ - char* (*get_description) (audio_driver_class_t *); - - /* - * free all class-related resources - */ - - void (*dispose) (audio_driver_class_t *); -}; - -/* - * this initiates the audio_out sync routines - * found in ./src/xine-engine/audio_out.c - */ -xine_audio_port_t *_x_ao_new_port (xine_t *xine, ao_driver_t *driver, int grab_only) XINE_PROTECTED; - -/* - * audio output modes + capabilities - */ - -#define AO_CAP_NOCAP 0x00000000 /* driver has no capabilities */ -#define AO_CAP_MODE_A52 0x00000001 /* driver supports A/52 output */ -#define AO_CAP_MODE_AC5 0x00000002 /* driver supports AC5 output */ -/* 1 sample == 2 bytes (C) */ -#define AO_CAP_MODE_MONO 0x00000004 /* driver supports mono output */ -/* 1 sample == 4 bytes (L,R) */ -#define AO_CAP_MODE_STEREO 0x00000008 /* driver supports stereo output */ -/* 1 sample == 8 bytes (L,R,LR,RR) */ -#define AO_CAP_MODE_4CHANNEL 0x00000010 /* driver supports 4 channels */ -/* - * Sound cards generally support, 1,2,4,6 channels, but rarely 5. - * So xine will take 4.1, 5 and 6 channel a52 streams and - * down or upmix it correctly to fill the 6 output channels. - * Are there any requests for 2.1 out there? - */ -/* 1 sample == 12 bytes (L,R,LR,RR,Null,LFE) */ -#define AO_CAP_MODE_4_1CHANNEL 0x00000020 /* driver supports 4.1 channels */ -/* 1 sample == 12 bytes (L,R,LR,RR,C, Null) */ -#define AO_CAP_MODE_5CHANNEL 0x00000040 /* driver supports 5 channels */ -/* 1 sample == 12 bytes (L,R,LR,RR,C,LFE) */ -#define AO_CAP_MODE_5_1CHANNEL 0x00000080 /* driver supports 5.1 channels */ - -/* - * converts the audio output mode into the number of channels - */ -int _x_ao_mode2channels( int mode ) XINE_PROTECTED; -/* - * converts the number of channels into the audio output mode - */ -int _x_ao_channels2mode( int channels ) XINE_PROTECTED; - -#define AO_CAP_MIXER_VOL 0x00000100 /* driver supports mixer control */ -#define AO_CAP_PCM_VOL 0x00000200 /* driver supports pcm control */ -#define AO_CAP_MUTE_VOL 0x00000400 /* driver can mute volume */ -#define AO_CAP_8BITS 0x00000800 /* driver support 8-bit samples */ -#define AO_CAP_16BITS 0x00001000 /* driver support 16-bit samples */ -#define AO_CAP_24BITS 0x00002000 /* driver support 24-bit samples */ -#define AO_CAP_FLOAT32 0x00004000 /* driver support 32-bit samples. i.e. Floats */ - -/* properties supported by get/set_property() */ -#define AO_PROP_MIXER_VOL 0 -#define AO_PROP_PCM_VOL 1 -#define AO_PROP_MUTE_VOL 2 -#define AO_PROP_COMPRESSOR 3 -#define AO_PROP_DISCARD_BUFFERS 4 -#define AO_PROP_BUFS_IN_FIFO 5 /* read-only */ -#define AO_PROP_AMP 6 /* amplifier */ -#define AO_PROP_EQ_30HZ 7 /* equalizer */ -#define AO_PROP_EQ_60HZ 8 /* equalizer */ -#define AO_PROP_EQ_125HZ 9 /* equalizer */ -#define AO_PROP_EQ_250HZ 10 /* equalizer */ -#define AO_PROP_EQ_500HZ 11 /* equalizer */ -#define AO_PROP_EQ_1000HZ 12 /* equalizer */ -#define AO_PROP_EQ_2000HZ 13 /* equalizer */ -#define AO_PROP_EQ_4000HZ 14 /* equalizer */ -#define AO_PROP_EQ_8000HZ 15 /* equalizer */ -#define AO_PROP_EQ_16000HZ 16 /* equalizer */ -#define AO_PROP_CLOSE_DEVICE 17 /* force closing audio device */ -#define AO_PROP_AMP_MUTE 18 /* amplifier mute */ -#define AO_PROP_NUM_STREAMS 19 /* read-only */ -#define AO_PROP_CLOCK_SPEED 20 /* inform audio_out that speed has changed */ -#define AO_NUM_PROPERTIES 21 - -/* audio device control ops */ -#define AO_CTRL_PLAY_PAUSE 0 -#define AO_CTRL_PLAY_RESUME 1 -#define AO_CTRL_FLUSH_BUFFERS 2 - -/* above that value audio frames are discarded */ -#define AO_MAX_GAP 15000 - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/xine-engine/broadcaster.c b/src/xine-engine/broadcaster.c index 8ab661d3e..2157f0550 100644 --- a/src/xine-engine/broadcaster.c +++ b/src/xine-engine/broadcaster.c @@ -17,10 +17,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * - * $Id: broadcaster.c,v 1.15 2007/01/19 01:23:06 dgp85 Exp $ - * * broadcaster.c - xine network broadcaster * * how it works: @@ -32,7 +30,6 @@ * - streams played on master will appear on every slave. * if master is not meant to use video/audio devices it may be started with * 'xine -V none -A none' - * */ #include <stdio.h> @@ -60,9 +57,9 @@ #include <dlfcn.h> #include <pthread.h> -#include "xine_internal.h" -#include "buffer.h" -#include "xineutils.h" +#include <xine/xine_internal.h> +#include <xine/buffer.h> +#include <xine/xineutils.h> #define QLEN 5 /* maximum connection queue length */ #define _BUFSIZ 512 @@ -111,9 +108,10 @@ static int sock_check_opened(int socket) { /* * Write to socket. */ -static int sock_data_write(xine_t *xine, int socket, char *buf, int len) { +static int sock_data_write(xine_t *xine, int socket, void *buf_gen, int len) { ssize_t size; int wlen = 0; + uint8_t *buf = buf_gen; if((socket < 0) || (buf == NULL)) return -1; @@ -137,11 +135,8 @@ static int sock_data_write(xine_t *xine, int socket, char *buf, int len) { return wlen; } -static int -#ifdef __GNUC__ -__attribute__((format (printf, 3, 4))) -#endif -sock_string_write(xine_t *xine, int socket, char *msg, ...) { +static int XINE_FORMAT_PRINTF(3, 4) +sock_string_write(xine_t *xine, int socket, const char *msg, ...) { char buf[_BUFSIZ]; va_list args; @@ -160,7 +155,7 @@ sock_string_write(xine_t *xine, int socket, char *msg, ...) { * this is the most important broadcaster function. * it sends data to every connected client (slaves). */ -static void broadcaster_data_write(broadcaster_t *this, char *buf, int len) { +static void broadcaster_data_write(broadcaster_t *this, void *buf, int len) { xine_list_iterator_t ite; ite = xine_list_front (this->connections); @@ -182,11 +177,8 @@ static void broadcaster_data_write(broadcaster_t *this, char *buf, int len) { } } -static void -#ifdef __GNUC__ -__attribute__((format (printf, 2, 3))) -#endif -broadcaster_string_write(broadcaster_t *this, char *msg, ...) { +static void XINE_FORMAT_PRINTF(2, 3) +broadcaster_string_write(broadcaster_t *this, const char *msg, ...) { char buf[_BUFSIZ]; va_list args; @@ -256,7 +248,7 @@ static void *manager_loop (void *this_gen) { /* * receive xine buffers and send them through the broadcaster */ -static void send_buf (broadcaster_t *this, char *from, buf_element_t *buf) { +static void send_buf (broadcaster_t *this, const char *from, buf_element_t *buf) { int i; /* ignore END buffers since they would stop the slavery */ @@ -358,6 +350,17 @@ broadcaster_t *_x_init_broadcaster(xine_stream_t *stream, int port) void _x_close_broadcaster(broadcaster_t *this) { + this->running = 0; + pthread_cancel(this->manager_thread); + pthread_join(this->manager_thread,NULL); + close(this->msock); + + if (this->stream->video_fifo) + this->stream->video_fifo->unregister_put_cb(this->stream->video_fifo, video_put_cb); + + if(this->stream->audio_fifo) + this->stream->audio_fifo->unregister_put_cb(this->stream->audio_fifo, audio_put_cb); + xine_list_iterator_t ite; while ( (ite = xine_list_front(this->connections)) ) { @@ -368,18 +371,9 @@ void _x_close_broadcaster(broadcaster_t *this) xine_list_remove (this->connections, ite); } xine_list_delete(this->connections); - - this->running = 0; - close(this->msock); - pthread_mutex_lock( &this->lock ); - pthread_cancel(this->manager_thread); - pthread_join(this->manager_thread,NULL); - - this->stream->video_fifo->unregister_put_cb(this->stream->video_fifo, video_put_cb); - if(this->stream->audio_fifo) - this->stream->audio_fifo->unregister_put_cb(this->stream->audio_fifo, audio_put_cb); - + pthread_mutex_destroy( &this->lock ); + free(this); } diff --git a/src/xine-engine/broadcaster.h b/src/xine-engine/broadcaster.h deleted file mode 100644 index bc0d2feab..000000000 --- a/src/xine-engine/broadcaster.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (C) 2000-2003 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - * - * $Id: broadcaster.h,v 1.3 2006/09/26 05:19:48 dgp85 Exp $ - * - * broadcaster.h - * - */ - -#ifndef HAVE_BROADCASTER_H -#define HAVE_BROADCASTER_H - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -typedef struct broadcaster_s broadcaster_t; - -broadcaster_t *_x_init_broadcaster(xine_stream_t *stream, int port) XINE_PROTECTED; -void _x_close_broadcaster(broadcaster_t *this) XINE_PROTECTED; -int _x_get_broadcaster_port(broadcaster_t *this) XINE_PROTECTED; - - -#ifdef __cplusplus -} -#endif - -#endif - diff --git a/src/xine-engine/bswap.h b/src/xine-engine/bswap.h index 3415a09b4..635c6ae3a 100644 --- a/src/xine-engine/bswap.h +++ b/src/xine-engine/bswap.h @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ #ifndef __BSWAP_H__ @@ -28,23 +28,23 @@ #include "ffmpeg_bswap.h" /* These are the Aligned variants */ -#define ABE_16(x) (be2me_16(*(uint16_t*)(x))) -#define ABE_32(x) (be2me_32(*(uint32_t*)(x))) -#define ABE_64(x) (be2me_64(*(uint64_t*)(x))) -#define ALE_16(x) (le2me_16(*(uint16_t*)(x))) -#define ALE_32(x) (le2me_32(*(uint32_t*)(x))) -#define ALE_64(x) (le2me_64(*(uint64_t*)(x))) +#define _X_ABE_16(x) (be2me_16(*(uint16_t*)(x))) +#define _X_ABE_32(x) (be2me_32(*(uint32_t*)(x))) +#define _X_ABE_64(x) (be2me_64(*(uint64_t*)(x))) +#define _X_ALE_16(x) (le2me_16(*(uint16_t*)(x))) +#define _X_ALE_32(x) (le2me_32(*(uint32_t*)(x))) +#define _X_ALE_64(x) (le2me_64(*(uint64_t*)(x))) -#define BE_16(x) (((uint16_t)(((uint8_t*)(x))[0]) << 8) | \ +#define _X_BE_16(x) (((uint16_t)(((uint8_t*)(x))[0]) << 8) | \ ((uint16_t)((uint8_t*)(x))[1])) -#define BE_24(x) (((uint32_t)(((uint8_t*)(x))[0]) << 16) | \ +#define _X_BE_24(x) (((uint32_t)(((uint8_t*)(x))[0]) << 16) | \ ((uint32_t)(((uint8_t*)(x))[1]) << 8) | \ ((uint32_t)(((uint8_t*)(x))[2]))) -#define BE_32(x) (((uint32_t)(((uint8_t*)(x))[0]) << 24) | \ +#define _X_BE_32(x) (((uint32_t)(((uint8_t*)(x))[0]) << 24) | \ ((uint32_t)(((uint8_t*)(x))[1]) << 16) | \ ((uint32_t)(((uint8_t*)(x))[2]) << 8) | \ ((uint32_t)((uint8_t*)(x))[3])) -#define BE_64(x) (((uint64_t)(((uint8_t*)(x))[0]) << 56) | \ +#define _X_BE_64(x) (((uint64_t)(((uint8_t*)(x))[0]) << 56) | \ ((uint64_t)(((uint8_t*)(x))[1]) << 48) | \ ((uint64_t)(((uint8_t*)(x))[2]) << 40) | \ ((uint64_t)(((uint8_t*)(x))[3]) << 32) | \ @@ -53,16 +53,16 @@ ((uint64_t)(((uint8_t*)(x))[6]) << 8) | \ ((uint64_t)((uint8_t*)(x))[7])) -#define LE_16(x) (((uint16_t)(((uint8_t*)(x))[1]) << 8) | \ +#define _X_LE_16(x) (((uint16_t)(((uint8_t*)(x))[1]) << 8) | \ ((uint16_t)((uint8_t*)(x))[0])) -#define LE_24(x) (((uint32_t)(((uint8_t*)(x))[2]) << 16) | \ +#define _X_LE_24(x) (((uint32_t)(((uint8_t*)(x))[2]) << 16) | \ ((uint32_t)(((uint8_t*)(x))[1]) << 8) | \ ((uint32_t)(((uint8_t*)(x))[0]))) -#define LE_32(x) (((uint32_t)(((uint8_t*)(x))[3]) << 24) | \ +#define _X_LE_32(x) (((uint32_t)(((uint8_t*)(x))[3]) << 24) | \ ((uint32_t)(((uint8_t*)(x))[2]) << 16) | \ ((uint32_t)(((uint8_t*)(x))[1]) << 8) | \ ((uint32_t)((uint8_t*)(x))[0])) -#define LE_64(x) (((uint64_t)(((uint8_t*)(x))[7]) << 56) | \ +#define _X_LE_64(x) (((uint64_t)(((uint8_t*)(x))[7]) << 56) | \ ((uint64_t)(((uint8_t*)(x))[6]) << 48) | \ ((uint64_t)(((uint8_t*)(x))[5]) << 40) | \ ((uint64_t)(((uint8_t*)(x))[4]) << 32) | \ @@ -72,19 +72,19 @@ ((uint64_t)((uint8_t*)(x))[0])) #ifdef WORDS_BIGENDIAN -#define ME_16(x) BE_16(x) -#define ME_32(x) BE_32(x) -#define ME_64(x) BE_64(x) -#define AME_16(x) ABE_16(x) -#define AME_32(x) ABE_32(x) -#define AME_64(x) ABE_64(x) +#define _X_ME_16(x) _X_BE_16(x) +#define _X_ME_32(x) _X_BE_32(x) +#define _X_ME_64(x) _X_BE_64(x) +#define _X_AME_16(x) _X_ABE_16(x) +#define _X_AME_32(x) _X_ABE_32(x) +#define _X_AME_64(x) _X_ABE_64(x) #else -#define ME_16(x) LE_16(x) -#define ME_32(x) LE_32(x) -#define ME_64(x) LE_64(x) -#define AME_16(x) ALE_16(x) -#define AME_32(x) ALE_32(x) -#define AME_64(x) ALE_64(x) +#define _X_ME_16(x) _X_LE_16(x) +#define _X_ME_32(x) _X_LE_32(x) +#define _X_ME_64(x) _X_LE_64(x) +#define _X_AME_16(x) _X_ALE_16(x) +#define _X_AME_32(x) _X_ALE_32(x) +#define _X_AME_64(x) _X_ALE_64(x) #endif #define BE_FOURCC( ch0, ch1, ch2, ch3 ) \ diff --git a/src/xine-engine/buffer.c b/src/xine-engine/buffer.c index 389146dcb..8b8a8334a 100644 --- a/src/xine-engine/buffer.c +++ b/src/xine-engine/buffer.c @@ -15,9 +15,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - * - * $Id: buffer.c,v 1.37 2006/12/25 21:59:32 dgp85 Exp $ + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * * contents: @@ -28,7 +26,6 @@ * free buffer pool management routines * * FIFO buffer structures/routines - * */ #ifdef HAVE_CONFIG_H @@ -46,9 +43,9 @@ #define LOG */ -#include "buffer.h" -#include "xineutils.h" -#include "xine_internal.h" +#include <xine/buffer.h> +#include <xine/xineutils.h> +#include <xine/xine_internal.h> /* * put a previously allocated buffer element back into the buffer pool diff --git a/src/xine-engine/buffer.h b/src/xine-engine/buffer.h deleted file mode 100644 index 64fe52a20..000000000 --- a/src/xine-engine/buffer.h +++ /dev/null @@ -1,678 +0,0 @@ -/* - * Copyright (C) 2000-2004 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - * - * $Id: buffer.h,v 1.162 2007/01/14 16:53:37 klan Exp $ - * - * - * contents: - * - * buffer_entry structure - serves as a transport encapsulation - * of the mpeg audio/video data through xine - * - * free buffer pool management routines - * - * FIFO buffer structures/routines - * - */ - -#ifndef HAVE_BUFFER_H -#define HAVE_BUFFER_H - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <stdio.h> -#include <pthread.h> -#include <sys/types.h> - -#ifdef XINE_COMPILE -# include <inttypes.h> -# include "attributes.h" -#else -# include <xine/os_types.h> -# include <xine/attributes.h> -#endif - -#define BUF_MAX_CALLBACKS 5 - -/* - * buffer types - * - * a buffer type ID describes the contents of a buffer - * it consists of three fields: - * - * buf_type = 0xMMDDCCCC - * - * MM : major buffer type (CONTROL, VIDEO, AUDIO, SPU) - * 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 */ - -#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_NOP 0x01040000 -#define BUF_CONTROL_AUDIO_CHANNEL 0x01050000 -#define BUF_CONTROL_SPU_CHANNEL 0x01060000 -#define BUF_CONTROL_NEWPTS 0x01070000 -#define BUF_CONTROL_RESET_DECODER 0x01080000 -#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) */ - -#define BUF_VIDEO_BASE 0x02000000 -#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 -#define BUF_VIDEO_SORENSON_V1 0x02030000 -#define BUF_VIDEO_MSMPEG4_V2 0x02040000 -#define BUF_VIDEO_MSMPEG4_V3 0x02050000 -#define BUF_VIDEO_MJPEG 0x02060000 -#define BUF_VIDEO_IV50 0x02070000 -#define BUF_VIDEO_IV41 0x02080000 -#define BUF_VIDEO_IV32 0x02090000 -#define BUF_VIDEO_IV31 0x020a0000 -#define BUF_VIDEO_ATIVCR1 0x020b0000 -#define BUF_VIDEO_ATIVCR2 0x020c0000 -#define BUF_VIDEO_I263 0x020d0000 -#define BUF_VIDEO_RV10 0x020e0000 -#define BUF_VIDEO_RGB 0x02100000 -#define BUF_VIDEO_YUY2 0x02110000 -#define BUF_VIDEO_JPEG 0x02120000 -#define BUF_VIDEO_WMV7 0x02130000 -#define BUF_VIDEO_WMV8 0x02140000 -#define BUF_VIDEO_MSVC 0x02150000 -#define BUF_VIDEO_DV 0x02160000 -#define BUF_VIDEO_REAL 0x02170000 -#define BUF_VIDEO_VP31 0x02180000 -#define BUF_VIDEO_H263 0x02190000 -#define BUF_VIDEO_3IVX 0x021A0000 -#define BUF_VIDEO_CYUV 0x021B0000 -#define BUF_VIDEO_DIVX5 0x021C0000 -#define BUF_VIDEO_XVID 0x021D0000 -#define BUF_VIDEO_SMC 0x021E0000 -#define BUF_VIDEO_RPZA 0x021F0000 -#define BUF_VIDEO_QTRLE 0x02200000 -#define BUF_VIDEO_MSRLE 0x02210000 -#define BUF_VIDEO_DUCKTM1 0x02220000 -#define BUF_VIDEO_FLI 0x02230000 -#define BUF_VIDEO_ROQ 0x02240000 -#define BUF_VIDEO_SORENSON_V3 0x02250000 -#define BUF_VIDEO_MSMPEG4_V1 0x02260000 -#define BUF_VIDEO_MSS1 0x02270000 -#define BUF_VIDEO_IDCIN 0x02280000 -#define BUF_VIDEO_PGVV 0x02290000 -#define BUF_VIDEO_ZYGO 0x022A0000 -#define BUF_VIDEO_TSCC 0x022B0000 -#define BUF_VIDEO_YVU9 0x022C0000 -#define BUF_VIDEO_VQA 0x022D0000 -#define BUF_VIDEO_GREY 0x022E0000 -#define BUF_VIDEO_XXAN 0x022F0000 -#define BUF_VIDEO_WC3 0x02300000 -#define BUF_VIDEO_YV12 0x02310000 -#define BUF_VIDEO_SEGA 0x02320000 -#define BUF_VIDEO_RV20 0x02330000 -#define BUF_VIDEO_RV30 0x02340000 -#define BUF_VIDEO_MVI2 0x02350000 -#define BUF_VIDEO_UCOD 0x02360000 -#define BUF_VIDEO_WMV9 0x02370000 -#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_HUFFYUV 0x023C0000 -#define BUF_VIDEO_IMAGE 0x023D0000 -#define BUF_VIDEO_THEORA 0x023E0000 -#define BUF_VIDEO_4XM 0x023F0000 -#define BUF_VIDEO_I420 0x02400000 -#define BUF_VIDEO_VP4 0x02410000 -#define BUF_VIDEO_VP5 0x02420000 -#define BUF_VIDEO_VP6 0x02430000 -#define BUF_VIDEO_VMD 0x02440000 -#define BUF_VIDEO_MSZH 0x02450000 -#define BUF_VIDEO_ZLIB 0x02460000 -#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_FLV1 0x024C0000 -#define BUF_VIDEO_H264 0x024D0000 -#define BUF_VIDEO_MJPEG_B 0x024E0000 -#define BUF_VIDEO_H261 0x024F0000 -#define BUF_VIDEO_AASC 0x02500000 -#define BUF_VIDEO_LOCO 0x02510000 -#define BUF_VIDEO_QDRW 0x02520000 -#define BUF_VIDEO_QPEG 0x02530000 -#define BUF_VIDEO_ULTI 0x02540000 -#define BUF_VIDEO_WNV1 0x02550000 -#define BUF_VIDEO_XL 0x02560000 -#define BUF_VIDEO_RT21 0x02570000 -#define BUF_VIDEO_FPS1 0x02580000 -#define BUF_VIDEO_DUCKTM2 0x02590000 -#define BUF_VIDEO_CSCD 0x025A0000 -#define BUF_VIDEO_ALGMM 0x025B0000 -#define BUF_VIDEO_ZMBV 0x025C0000 -#define BUF_VIDEO_AVS 0x025D0000 -#define BUF_VIDEO_SMACKER 0x025E0000 -#define BUF_VIDEO_NUV 0x025F0000 -#define BUF_VIDEO_KMVC 0x02600000 -#define BUF_VIDEO_FLASHSV 0x02610000 -#define BUF_VIDEO_CAVS 0x02620000 -#define BUF_VIDEO_VP6F 0x02630000 - -/* audio buffer types: (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_A52 0x03000000 -#define BUF_AUDIO_MPEG 0x03010000 -#define BUF_AUDIO_LPCM_BE 0x03020000 -#define BUF_AUDIO_LPCM_LE 0x03030000 -#define BUF_AUDIO_WMAV1 0x03040000 -#define BUF_AUDIO_DTS 0x03050000 -#define BUF_AUDIO_MSADPCM 0x03060000 -#define BUF_AUDIO_MSIMAADPCM 0x03070000 -#define BUF_AUDIO_MSGSM 0x03080000 -#define BUF_AUDIO_VORBIS 0x03090000 -#define BUF_AUDIO_IMC 0x030a0000 -#define BUF_AUDIO_LH 0x030b0000 -#define BUF_AUDIO_VOXWARE 0x030c0000 -#define BUF_AUDIO_ACELPNET 0x030d0000 -#define BUF_AUDIO_AAC 0x030e0000 -#define BUF_AUDIO_DNET 0x030f0000 -#define BUF_AUDIO_VIVOG723 0x03100000 -#define BUF_AUDIO_DK3ADPCM 0x03110000 -#define BUF_AUDIO_DK4ADPCM 0x03120000 -#define BUF_AUDIO_ROQ 0x03130000 -#define BUF_AUDIO_QTIMAADPCM 0x03140000 -#define BUF_AUDIO_MAC3 0x03150000 -#define BUF_AUDIO_MAC6 0x03160000 -#define BUF_AUDIO_QDESIGN1 0x03170000 -#define BUF_AUDIO_QDESIGN2 0x03180000 -#define BUF_AUDIO_QCLP 0x03190000 -#define BUF_AUDIO_SMJPEG_IMA 0x031A0000 -#define BUF_AUDIO_VQA_IMA 0x031B0000 -#define BUF_AUDIO_MULAW 0x031C0000 -#define BUF_AUDIO_ALAW 0x031D0000 -#define BUF_AUDIO_GSM610 0x031E0000 -#define BUF_AUDIO_EA_ADPCM 0x031F0000 -#define BUF_AUDIO_WMAV2 0x03200000 -#define BUF_AUDIO_COOK 0x03210000 -#define BUF_AUDIO_ATRK 0x03220000 -#define BUF_AUDIO_14_4 0x03230000 -#define BUF_AUDIO_28_8 0x03240000 -#define BUF_AUDIO_SIPRO 0x03250000 -#define BUF_AUDIO_WMAV3 0x03260000 -#define BUF_AUDIO_INTERPLAY 0x03270000 -#define BUF_AUDIO_XA_ADPCM 0x03280000 -#define BUF_AUDIO_WESTWOOD 0x03290000 -#define BUF_AUDIO_DIALOGIC_IMA 0x032A0000 -#define BUF_AUDIO_NSF 0x032B0000 -#define BUF_AUDIO_FLAC 0x032C0000 -#define BUF_AUDIO_DV 0x032D0000 -#define BUF_AUDIO_WMAV 0x032E0000 -#define BUF_AUDIO_SPEEX 0x032F0000 -#define BUF_AUDIO_RAWPCM 0x03300000 -#define BUF_AUDIO_4X_ADPCM 0x03310000 -#define BUF_AUDIO_VMD 0x03320000 -#define BUF_AUDIO_XAN_DPCM 0x03330000 -#define BUF_AUDIO_ALAC 0x03340000 -#define BUF_AUDIO_MPC 0x03350000 -#define BUF_AUDIO_SHORTEN 0x03360000 -#define BUF_AUDIO_WESTWOOD_SND1 0x03370000 -#define BUF_AUDIO_WMALL 0x03380000 -#define BUF_AUDIO_TRUESPEECH 0x03390000 -#define BUF_AUDIO_TTA 0x033A0000 -#define BUF_AUDIO_SMACKER 0x033B0000 -#define BUF_AUDIO_FLVADPCM 0x033C0000 -#define BUF_AUDIO_WAVPACK 0x033D0000 - -/* spu buffer types: */ - -#define BUF_SPU_BASE 0x04000000 -#define BUF_SPU_DVD 0x04000000 -#define BUF_SPU_TEXT 0x04010000 -#define BUF_SPU_CC 0x04020000 -#define BUF_SPU_DVB 0x04030000 -#define BUF_SPU_SVCD 0x04040000 -#define BUF_SPU_CVD 0x04050000 -#define BUF_SPU_OGM 0x04060000 -#define BUF_SPU_CMML 0x04070000 - -/* 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. - */ - -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 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 */ -}; - - -#define BUF_NUM_DEC_INFO 5 - -typedef struct buf_element_s buf_element_t; -struct buf_element_s { - buf_element_t *next; - - unsigned char *mem; - 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 */ - - extra_info_t *extra_info; /* extra info will be passed to frames */ - - uint32_t decoder_flags; /* stuff like keyframe, is_header ... see below */ - - /* additional decoder flags and other dec-spec. stuff */ - uint32_t decoder_info[BUF_NUM_DEC_INFO]; - /* 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 */ - -} ; - -/* 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 */ -#define BUF_FLAG_FRAME_START 0x0002 -#define BUF_FLAG_FRAME_END 0x0004 - -/* 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 - * 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 */ -#define BUF_FLAG_END_USER 0x0020 - -/* set when stream finished naturaly */ -#define BUF_FLAG_END_STREAM 0x0040 - -/* decoder_info[0] carries the frame step (1/90000). */ -#define BUF_FLAG_FRAMERATE 0x0080 - -/* hint to metronom that seeking has occurred */ -#define BUF_FLAG_SEEK 0x0100 - -/* special information inside, see below. */ -#define BUF_FLAG_SPECIAL 0x0200 - -/* 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[2] carries denominator for display aspect ratio */ -#define BUF_FLAG_ASPECT 0x0800 - - -/* 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 - * offers a way to communicate this or any other custom, format-specific - * data to the decoder. - * - * The interface was designed in a way that did not require an API - * version bump. To send a special buffer type, set a buffer's flags field - * to BUF_FLAG_SPECIAL. Set the buffer's decoder_info[1] field to a - * number according to one of the special buffer subtypes defined below. - * The second and third decoder_info[] fields are defined according to - * your buffer type's requirements. - * - * Finally, remember to set the buffer's size to 0. This way, if a special - * buffer is sent to a decode that does not know how to handle it, the - * 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 - * decoder_info_ptr[2] = pointer to palette table - * This buffer type is used to provide a file- and decoder-independent - * facility to transport RGB color palettes from demuxers to decoders. - * A palette table is an array of palette_entry_t structures. A decoder - * should not count on this array to exist for the duration of the - * program's execution and should copy, manipulate, and store the palette - * data privately if it needs the palette information. - */ -#define BUF_SPECIAL_PALETTE 1 - - -/* 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 - * decoder_info[3] = stream scale prohibitions - * This buffer is used to force mpeg decoders to use a certain aspect. - * Currently xine-dvdnav uses this, because it has more accurate information - * about the aspect from the dvd ifo-data. - * The stream scale prohibitions are also delivered, with bit 0 meaning - * "deny letterboxing" and bit 1 meaning "deny pan&scan" - */ -#define BUF_SPECIAL_ASPECT 3 - -/* - * In a BUF_SPECIAL_DECODER_CONFIG buffer: - * decoder_info[1] = BUF_SPECIAL_DECODER_CONFIG - * decoder_info[2] = data size - * decoder_info_ptr[2] = pointer to data - * This buffer is used to pass config information from .mp4 files - * (atom esds) to decoders. both mpeg4 and aac streams use that. - */ -#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 - * four length bytes at the beginning - * decoder_info_ptr[2] = pointer to ImageDescription atom, starting with - * the codec fourcc - * Some Quicktime decoders need information contained within the - * ImageDescription atom inside a Quicktime file's stsd atom. This - * special buffer carries the ImageDescription atom from the QT demuxer - * to an A/V decoder. - */ -#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 - * lpcm data encoded into mpeg2 streams have a format configuration - * byte in every frame. this is used to detect the sample rate, - * number of bits and channels. - */ -#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 - * decoder_info_ptr[2] = pointer to charset encoding string - * This is used mostly with subtitle buffers when encoding is - * known at demuxer level (take precedence over xine config - * settings such as subtitles.separate.src_encoding) - */ -#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 - * decoder_info[3] = - * This buffer is pass SPU subtypes from DVDs - */ -#define BUF_SPECIAL_SPU_DVD_SUBTYPE 8 - - -#define SPU_DVD_SUBTYPE_CLUT 1 -#define SPU_DVD_SUBTYPE_PACKAGE 2 -#define SPU_DVD_SUBTYPE_VOBSUB_PACKAGE 3 -#define SPU_DVD_SUBTYPE_NAV 4 - -/* 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 - * decoder_info[3] = - * - * This buffer is used to tell a DVBSUB decoder when the stream - * changes. For more information on how to write a DVBSUB decoder, - * see the comment at the top of src/demuxers/demux_ts.c - **/ -#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 - * decoder_info_ptr[2] = pointer to the chunk table - * - * 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 -{ - char lang[4]; - long comp_page_id; - long aux_page_id; -} ; - -typedef struct palette_entry_s palette_entry_t; -struct palette_entry_s -{ - unsigned char r, g, b; -} ; - -typedef struct fifo_buffer_s fifo_buffer_t; -struct fifo_buffer_s -{ - buf_element_t *first, *last; - - int fifo_size; - uint32_t fifo_data_size; - void *fifo_empty_cb_data; - - pthread_mutex_t mutex; - pthread_cond_t not_empty; - - /* - * functions to access this fifo: - */ - - void (*put) (fifo_buffer_t *fifo, buf_element_t *buf); - - buf_element_t *(*get) (fifo_buffer_t *fifo); - - void (*clear) (fifo_buffer_t *fifo) ; - - int (*size) (fifo_buffer_t *fifo); - - int (*num_free) (fifo_buffer_t *fifo); - - uint32_t (*data_size) (fifo_buffer_t *fifo); - - void (*dispose) (fifo_buffer_t *fifo); - - /* - * alloc buffer for this fifo from global buf pool - * you don't have to use this function to allocate a buffer, - * an input plugin can decide to implement it's own - * buffer allocation functions - */ - - buf_element_t *(*buffer_pool_alloc) (fifo_buffer_t *self); - - - /* - * special functions, not used by demuxers - */ - - /* the same as buffer_pool_alloc but may fail if none is available */ - buf_element_t *(*buffer_pool_try_alloc) (fifo_buffer_t *self); - - /* the same as put but insert at the head of the fifo */ - void (*insert) (fifo_buffer_t *fifo, buf_element_t *buf); - - /* callbacks */ - void (*register_alloc_cb) (fifo_buffer_t *fifo, void (*cb)(fifo_buffer_t *fifo, void *), void *cb_data); - void (*register_put_cb) (fifo_buffer_t *fifo, void (*cb)(fifo_buffer_t *fifo, buf_element_t *buf, void *), void *cb_data); - void (*register_get_cb) (fifo_buffer_t *fifo, void (*cb)(fifo_buffer_t *fifo, buf_element_t *buf, void *), void *cb_data); - void (*unregister_alloc_cb) (fifo_buffer_t *fifo, void (*cb)(fifo_buffer_t *fifo, void *)); - void (*unregister_put_cb) (fifo_buffer_t *fifo, void (*cb)(fifo_buffer_t *fifo, buf_element_t *buf, void *)); - void (*unregister_get_cb) (fifo_buffer_t *fifo, void (*cb)(fifo_buffer_t *fifo, buf_element_t *buf, void *)); - - /* - * private variables for buffer pool management - */ - buf_element_t *buffer_pool_top; /* a stack actually */ - pthread_mutex_t buffer_pool_mutex; - pthread_cond_t buffer_pool_cond_not_empty; - int buffer_pool_num_free; - int buffer_pool_capacity; - int buffer_pool_buf_size; - void *buffer_pool_base; /*used to free mem chunk */ - void (*alloc_cb[BUF_MAX_CALLBACKS])(fifo_buffer_t *fifo, void *data_cb); - void (*put_cb[BUF_MAX_CALLBACKS])(fifo_buffer_t *fifo, buf_element_t *buf, void *data_cb); - void (*get_cb[BUF_MAX_CALLBACKS])(fifo_buffer_t *fifo, buf_element_t *buf, void *data_cb); - void *alloc_cb_data[BUF_MAX_CALLBACKS]; - void *put_cb_data[BUF_MAX_CALLBACKS]; - 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 - */ - -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; - - -/* return BUF_VIDEO_xxx given the fourcc - * fourcc_int must be read in machine endianness - * 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; - -/* return BUF_AUDIO_xxx given the formattag */ -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; - - -#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. - */ -typedef struct __attribute__((__packed__)) { - int32_t biSize; - int32_t biWidth; - int32_t biHeight; - int16_t biPlanes; - int16_t biBitCount; - uint32_t biCompression; - int32_t biSizeImage; - int32_t biXPelsPerMeter; - int32_t biYPelsPerMeter; - int32_t biClrUsed; - int32_t biClrImportant; -} xine_bmiheader; - -/* this is xine version of WAVEFORMATEX - * (the same comments from xine_bmiheader) - */ -typedef struct __attribute__((__packed__)) { - int16_t wFormatTag; - int16_t nChannels; - int32_t nSamplesPerSec; - int32_t nAvgBytesPerSec; - int16_t nBlockAlign; - int16_t wBitsPerSample; - int16_t cbSize; -} xine_waveformatex; -#ifndef ATTRIBUTE_PACKED -#pragma pack() -#endif - -/* convert xine_bmiheader struct from little endian */ -void _x_bmiheader_le2me( xine_bmiheader *bih ) XINE_PROTECTED; - -/* convert xine_waveformatex struct from little endian */ -void _x_waveformatex_le2me( xine_waveformatex *wavex ) XINE_PROTECTED; - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/xine-engine/buffer_types.c b/src/xine-engine/buffer_types.c index 4a71a99c2..c7b6ae860 100644 --- a/src/xine-engine/buffer_types.c +++ b/src/xine-engine/buffer_types.c @@ -15,16 +15,13 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - * - * $Id: buffer_types.c,v 1.107 2006/12/26 03:18:56 dgp85 Exp $ + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * * contents: * * buffer types management. * convert FOURCC and audioformattag to BUF_xxx defines - * */ #ifdef HAVE_CONFIG_H @@ -35,38 +32,31 @@ #include <string.h> #include <stdlib.h> #include <inttypes.h> -#include "buffer.h" +#include <xine/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; - const char name[]; + const char *name; } video_db_t; typedef struct audio_db_s { uint32_t formattag[10]; uint32_t buf_type; - const char name[]; + const char *name; } audio_db_t; -static video_db_t video_db[] = { +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'), + 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, @@ -74,15 +64,15 @@ static 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, @@ -90,8 +80,8 @@ static 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, @@ -99,7 +89,7 @@ static video_db_t video_db[] = { }, { { - meFOURCC('D', 'X', '5', '0'), + ME_FOURCC('D', 'X', '5', '0'), 0 }, BUF_VIDEO_DIVX5, @@ -107,7 +97,7 @@ static video_db_t video_db[] = { }, { { - meFOURCC('c', 'v', 'i', 'd'), + ME_FOURCC('c', 'v', 'i', 'd'), 0 }, BUF_VIDEO_CINEPAK, @@ -115,9 +105,9 @@ static 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, @@ -125,8 +115,8 @@ static 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, @@ -134,10 +124,10 @@ static 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, @@ -145,12 +135,12 @@ static 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, @@ -158,20 +148,20 @@ static 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, @@ -179,8 +169,8 @@ static 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, @@ -188,11 +178,11 @@ static 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, @@ -200,7 +190,7 @@ static video_db_t video_db[] = { }, { { - meFOURCC('m', 'j', 'p', 'b'), + ME_FOURCC('m', 'j', 'p', 'b'), 0 }, BUF_VIDEO_MJPEG_B, @@ -208,8 +198,8 @@ static 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, @@ -217,8 +207,8 @@ static 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, @@ -226,8 +216,8 @@ static 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, @@ -235,8 +225,8 @@ static 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, @@ -244,7 +234,7 @@ static video_db_t video_db[] = { }, { { - meFOURCC('V', 'C', 'R', '1'), + ME_FOURCC('V', 'C', 'R', '1'), 0 }, BUF_VIDEO_ATIVCR1, @@ -252,7 +242,7 @@ static video_db_t video_db[] = { }, { { - meFOURCC('V', 'C', 'R', '2'), + ME_FOURCC('V', 'C', 'R', '2'), 0 }, BUF_VIDEO_ATIVCR2, @@ -260,11 +250,11 @@ static 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, @@ -272,8 +262,8 @@ static 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, @@ -285,8 +275,8 @@ static 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, @@ -294,8 +284,8 @@ static 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, @@ -303,7 +293,7 @@ static video_db_t video_db[] = { }, { { - meFOURCC('W','M','V','1'), + ME_FOURCC('W','M','V','1'), 0 }, BUF_VIDEO_WMV7, @@ -311,7 +301,7 @@ static video_db_t video_db[] = { }, { { - meFOURCC('W','M','V','2'), + ME_FOURCC('W','M','V','2'), 0 }, BUF_VIDEO_WMV8, @@ -319,8 +309,8 @@ static 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, @@ -328,12 +318,22 @@ static 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('W','V','C','1'), + ME_FOURCC('W','M','V','A'), + ME_FOURCC('v','c','-','1'), + 0 + }, + BUF_VIDEO_VC1, + "Windows Media Video VC-1" +}, +{ + { + 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, @@ -341,9 +341,9 @@ static 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, @@ -351,11 +351,11 @@ static 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, @@ -363,7 +363,7 @@ static video_db_t video_db[] = { }, { { - meFOURCC('V','P','4','0'), + ME_FOURCC('V','P','4','0'), 0, }, BUF_VIDEO_VP4, @@ -371,10 +371,10 @@ static 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, @@ -382,8 +382,8 @@ static 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, @@ -391,7 +391,7 @@ static video_db_t video_db[] = { }, { { - meFOURCC('s', 'm', 'c', ' '), + ME_FOURCC('s', 'm', 'c', ' '), 0 }, BUF_VIDEO_SMC, @@ -399,8 +399,8 @@ static 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, @@ -408,7 +408,7 @@ static video_db_t video_db[] = { }, { { - meFOURCC('r', 'l', 'e', ' '), + ME_FOURCC('r', 'l', 'e', ' '), 0 }, BUF_VIDEO_QTRLE, @@ -423,7 +423,7 @@ static video_db_t video_db[] = { }, { { - meFOURCC('D', 'U', 'C', 'K'), + ME_FOURCC('D', 'U', 'C', 'K'), 0 }, BUF_VIDEO_DUCKTM1, @@ -431,7 +431,7 @@ static video_db_t video_db[] = { }, { { - meFOURCC('M', 'S', 'S', '1'), + ME_FOURCC('M', 'S', 'S', '1'), 0 }, BUF_VIDEO_MSS1, @@ -439,7 +439,7 @@ static video_db_t video_db[] = { }, { { - meFOURCC('P', 'G', 'V', 'V'), + ME_FOURCC('P', 'G', 'V', 'V'), 0 }, BUF_VIDEO_PGVV, @@ -447,7 +447,7 @@ static video_db_t video_db[] = { }, { { - meFOURCC('Z', 'y', 'G', 'o'), + ME_FOURCC('Z', 'y', 'G', 'o'), 0 }, BUF_VIDEO_ZYGO, @@ -455,7 +455,7 @@ static video_db_t video_db[] = { }, { { - meFOURCC('t', 's', 'c', 'c'), + ME_FOURCC('t', 's', 'c', 'c'), 0 }, BUF_VIDEO_TSCC, @@ -463,7 +463,7 @@ static video_db_t video_db[] = { }, { { - meFOURCC('Y', 'V', 'U', '9'), + ME_FOURCC('Y', 'V', 'U', '9'), 0 }, BUF_VIDEO_YVU9, @@ -471,7 +471,7 @@ static video_db_t video_db[] = { }, { { - meFOURCC('G', 'R', 'E', 'Y'), + ME_FOURCC('G', 'R', 'E', 'Y'), 0 }, BUF_VIDEO_GREY, @@ -479,9 +479,9 @@ static 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, @@ -489,8 +489,8 @@ static 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, @@ -498,8 +498,8 @@ static 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, @@ -507,8 +507,8 @@ static 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, @@ -516,8 +516,8 @@ static 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, @@ -525,8 +525,8 @@ static 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, @@ -534,7 +534,7 @@ static video_db_t video_db[] = { }, { { - meFOURCC('R', 'V', '1', '0'), + ME_FOURCC('R', 'V', '1', '0'), 0 }, BUF_VIDEO_RV10, @@ -542,7 +542,7 @@ static video_db_t video_db[] = { }, { { - meFOURCC('R', 'V', '2', '0'), + ME_FOURCC('R', 'V', '2', '0'), 0 }, BUF_VIDEO_RV20, @@ -550,7 +550,7 @@ static video_db_t video_db[] = { }, { { - meFOURCC('R', 'V', '3', '0'), + ME_FOURCC('R', 'V', '3', '0'), 0 }, BUF_VIDEO_RV30, @@ -558,7 +558,7 @@ static video_db_t video_db[] = { }, { { - meFOURCC('R', 'V', '4', '0'), + ME_FOURCC('R', 'V', '4', '0'), 0 }, BUF_VIDEO_RV40, @@ -566,7 +566,7 @@ static video_db_t video_db[] = { }, { { - meFOURCC('H', 'F', 'Y', 'U'), + ME_FOURCC('H', 'F', 'Y', 'U'), 0, }, BUF_VIDEO_HUFFYUV, @@ -574,8 +574,8 @@ static 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, @@ -590,7 +590,7 @@ static video_db_t video_db[] = { }, { { - meFOURCC('V','P','5','0'), + ME_FOURCC('V','P','5','0'), 0 }, BUF_VIDEO_VP5, @@ -598,9 +598,9 @@ static 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, @@ -608,7 +608,15 @@ static video_db_t video_db[] = { }, { { - meFOURCC('8','B', 'P','S'), + ME_FOURCC('V','P','6','F'), + 0 + }, + BUF_VIDEO_VP6F, + "On2 VP6" +}, +{ + { + ME_FOURCC('8','B', 'P','S'), 0 }, BUF_VIDEO_8BPS, @@ -616,7 +624,7 @@ static video_db_t video_db[] = { }, { { - meFOURCC('Z','L','I','B'), + ME_FOURCC('Z','L','I','B'), 0 }, BUF_VIDEO_ZLIB, @@ -624,7 +632,7 @@ static video_db_t video_db[] = { }, { { - meFOURCC('M','S','Z','H'), + ME_FOURCC('M','S','Z','H'), 0 }, BUF_VIDEO_MSZH, @@ -632,7 +640,7 @@ static video_db_t video_db[] = { }, { { - meFOURCC('A','S','V','1'), + ME_FOURCC('A','S','V','1'), 0 }, BUF_VIDEO_ASV1, @@ -640,7 +648,7 @@ static video_db_t video_db[] = { }, { { - meFOURCC('A','S','V','2'), + ME_FOURCC('A','S','V','2'), 0 }, BUF_VIDEO_ASV2, @@ -648,9 +656,9 @@ static 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, @@ -658,7 +666,7 @@ static video_db_t video_db[] = { }, { { - meFOURCC('A','A','S','C'), + ME_FOURCC('A','A','S','C'), 0 }, BUF_VIDEO_AASC, @@ -666,7 +674,7 @@ static video_db_t video_db[] = { }, { { - meFOURCC('q','d','r','w'), + ME_FOURCC('q','d','r','w'), 0 }, BUF_VIDEO_QDRW, @@ -674,7 +682,7 @@ static video_db_t video_db[] = { }, { { - meFOURCC('L','O','C','O'), + ME_FOURCC('L','O','C','O'), 0 }, BUF_VIDEO_LOCO, @@ -682,7 +690,7 @@ static video_db_t video_db[] = { }, { { - meFOURCC('U','L','T','I'), + ME_FOURCC('U','L','T','I'), 0 }, BUF_VIDEO_ULTI, @@ -690,7 +698,7 @@ static video_db_t video_db[] = { }, { { - meFOURCC('W','N','V','1'), + ME_FOURCC('W','N','V','1'), 0 }, BUF_VIDEO_WNV1, @@ -698,8 +706,8 @@ static 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, @@ -707,9 +715,9 @@ static 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, @@ -717,7 +725,7 @@ static video_db_t video_db[] = { }, { { - meFOURCC('R','T','2','1'), + ME_FOURCC('R','T','2','1'), 0 }, BUF_VIDEO_RT21, @@ -725,7 +733,7 @@ static video_db_t video_db[] = { }, { { - meFOURCC('F','P','S','1'), + ME_FOURCC('F','P','S','1'), 0 }, BUF_VIDEO_FPS1, @@ -733,7 +741,7 @@ static video_db_t video_db[] = { }, { { - meFOURCC('T','M','2','0'), + ME_FOURCC('T','M','2','0'), 0 }, BUF_VIDEO_DUCKTM2, @@ -741,7 +749,7 @@ static video_db_t video_db[] = { }, { { - meFOURCC('C','S','C','D'), + ME_FOURCC('C','S','C','D'), 0 }, BUF_VIDEO_CSCD, @@ -749,7 +757,7 @@ static video_db_t video_db[] = { }, { { - meFOURCC('Z','M','B','V'), + ME_FOURCC('Z','M','B','V'), 0 }, BUF_VIDEO_ZMBV, @@ -757,21 +765,29 @@ static video_db_t video_db[] = { }, { { - meFOURCC('K','M','V','C'), + ME_FOURCC('K','M','V','C'), 0 }, BUF_VIDEO_KMVC, "Karl Morton's Video Codec" }, +{ + { + ME_FOURCC('V','M','n','c'), + 0 + }, + BUF_VIDEO_VMNC, + "VMware Screen Codec" +}, { { 0 }, 0, "last entry" } }; -static audio_db_t audio_db[] = { +static const audio_db_t audio_db[] = { { { 0x2000, - meFOURCC('m', 's', 0x20, 0x00), + ME_FOURCC('m', 's', 0x20, 0x00), 0 }, BUF_AUDIO_A52, @@ -780,9 +796,9 @@ static 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, @@ -790,8 +806,8 @@ static 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, @@ -800,8 +816,8 @@ static 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, @@ -852,7 +868,7 @@ static audio_db_t audio_db[] = { { { 0x02, - meFOURCC('m', 's', 0, 0x02), + ME_FOURCC('m', 's', 0, 0x02), 0 }, BUF_AUDIO_MSADPCM, @@ -861,7 +877,7 @@ static audio_db_t audio_db[] = { { { 0x11, - meFOURCC('m', 's', 0, 0x11), + ME_FOURCC('m', 's', 0, 0x11), 0 }, BUF_AUDIO_MSIMAADPCM, @@ -879,8 +895,8 @@ static 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, @@ -937,7 +953,7 @@ static audio_db_t audio_db[] = { }, { { - meFOURCC('i', 'm', 'a', '4'), + ME_FOURCC('i', 'm', 'a', '4'), 0 }, BUF_AUDIO_QTIMAADPCM, @@ -945,8 +961,8 @@ static 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, @@ -954,8 +970,8 @@ static 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, @@ -963,7 +979,7 @@ static audio_db_t audio_db[] = { }, { { - meFOURCC('Q', 'D', 'M', 'C'), + ME_FOURCC('Q', 'D', 'M', 'C'), 0 }, BUF_AUDIO_QDESIGN1, @@ -971,7 +987,7 @@ static audio_db_t audio_db[] = { }, { { - meFOURCC('Q', 'D', 'M', '2'), + ME_FOURCC('Q', 'D', 'M', '2'), 0 }, BUF_AUDIO_QDESIGN2, @@ -980,11 +996,11 @@ static 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, @@ -992,7 +1008,7 @@ static audio_db_t audio_db[] = { }, { { - meFOURCC('d', 'n', 'e', 't'), + ME_FOURCC('d', 'n', 'e', 't'), 0 }, BUF_AUDIO_DNET, @@ -1000,7 +1016,7 @@ static audio_db_t audio_db[] = { }, { { - meFOURCC('s', 'i', 'p', 'r'), + ME_FOURCC('s', 'i', 'p', 'r'), 0 }, BUF_AUDIO_SIPRO, @@ -1008,7 +1024,7 @@ static audio_db_t audio_db[] = { }, { { - meFOURCC('c', 'o', 'o', 'k'), + ME_FOURCC('c', 'o', 'o', 'k'), 0 }, BUF_AUDIO_COOK, @@ -1016,7 +1032,7 @@ static audio_db_t audio_db[] = { }, { { - meFOURCC('a', 't', 'r', 'c'), + ME_FOURCC('a', 't', 'r', 'c'), 0 }, BUF_AUDIO_ATRK, @@ -1024,7 +1040,7 @@ static audio_db_t audio_db[] = { }, { { - meFOURCC('Q', 'c', 'l', 'p'), + ME_FOURCC('Q', 'c', 'l', 'p'), 0 }, BUF_AUDIO_QCLP, @@ -1033,7 +1049,7 @@ static audio_db_t audio_db[] = { { { 0x7, - meFOURCC('u', 'l', 'a', 'w'), + ME_FOURCC('u', 'l', 'a', 'w'), 0 }, BUF_AUDIO_MULAW, @@ -1042,7 +1058,7 @@ static audio_db_t audio_db[] = { { { 0x6, - meFOURCC('a', 'l', 'a', 'w'), + ME_FOURCC('a', 'l', 'a', 'w'), 0 }, BUF_AUDIO_ALAW, @@ -1050,7 +1066,7 @@ static audio_db_t audio_db[] = { }, { { - meFOURCC('a', 'g', 's', 'm'), + ME_FOURCC('a', 'g', 's', 'm'), 0 }, BUF_AUDIO_GSM610, @@ -1072,7 +1088,7 @@ static audio_db_t audio_db[] = { }, { { - meFOURCC('l', 'p', 'c', 'J'), + ME_FOURCC('l', 'p', 'c', 'J'), 0 }, BUF_AUDIO_14_4, @@ -1080,7 +1096,7 @@ static audio_db_t audio_db[] = { }, { { - meFOURCC('2', '8', '_', '8'), + ME_FOURCC('2', '8', '_', '8'), 0 }, BUF_AUDIO_28_8, @@ -1095,7 +1111,7 @@ static audio_db_t audio_db[] = { }, { { - meFOURCC('a', 'l', 'a', 'c'), + ME_FOURCC('a', 'l', 'a', 'c'), }, BUF_AUDIO_ALAC, "Apple Lossless Audio Codec" @@ -1145,7 +1161,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; @@ -1179,7 +1195,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; @@ -1220,3 +1236,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.c b/src/xine-engine/configfile.c index 38f2c5a6c..550c0372f 100644 --- a/src/xine-engine/configfile.c +++ b/src/xine-engine/configfile.c @@ -15,12 +15,9 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - * - * $Id: configfile.c,v 1.85 2007/02/22 15:49:16 dgp85 Exp $ + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * config object (was: file) management - implementation - * */ #ifdef HAVE_CONFIG_H @@ -34,8 +31,8 @@ #include <stdlib.h> #include <string.h> #include <unistd.h> +#include <xine/configfile.h> #include "bswap.h" -#include "configfile.h" #define LOG_MODULE "configfile" #define LOG_VERBOSE @@ -43,16 +40,11 @@ #define LOG */ -#include "xineutils.h" -#include "xine_internal.h" - - -typedef struct { - const char *old; - const char *new; -} config_entry_translation_t; +#include <xine/xineutils.h> +#include <xine/xine_internal.h> -static config_entry_translation_t config_entry_translation[] = { +static const xine_config_entry_translation_t *config_entry_translation_user = NULL; +static const xine_config_entry_translation_t config_entry_translation[] = { { "audio.a52_pass_through", "" }, { "audio.alsa_a52_device", "audio.device.alsa_passthrough_device" }, { "audio.alsa_default_device", "audio.device.alsa_default_device" }, @@ -191,8 +183,6 @@ static config_entry_translation_t config_entry_translation[] = { { "video.pgx64_overlay_mode", "" }, { "video.pgx64_saturation", "video.output.pgx64_saturation" }, { "video.sdl_hw_accel", "video.device.sdl_hw_accel" }, - { "video.syncfb_default_repeat", "video.device.syncfb_default_repeat" }, - { "video.syncfb_device", "video.device.syncfb_device" }, { "video.unichrome_cpu_save", "video.device.unichrome_cpu_save" }, { "video.vertical_position", "video.output.vertical_position" }, { "video.vidix_blue_intensity", "video.output.vidix_blue_intensity" }, @@ -210,12 +200,13 @@ static config_entry_translation_t config_entry_translation[] = { { "video.xv_colorkey", "video.device.xv_colorkey" }, { "video.xv_pitch_alignment", "video.device.xv_pitch_alignment" }, { "video.xvmc_more_frames", "video.device.xvmc_more_frames" }, - { "video.xvmc_nvidia_color_fix", "video.device.xvmc_nvidia_color_fix" } + { "video.xvmc_nvidia_color_fix", "video.device.xvmc_nvidia_color_fix" }, + {} }; static int config_section_enum(const char *sect) { - static char *known_section[] = { + static const char *const known_section[] = { "gui", "ui", "audio", @@ -355,6 +346,15 @@ static void config_remove(config_values_t *this, cfg_entry_t *entry, cfg_entry_t prev->next = entry->next; } +static char *config_xlate_internal (const char *key, const xine_config_entry_translation_t *trans) +{ + --trans; + while ((++trans)->old_name) + if (trans->new_name[0] && strcmp(key, trans->old_name) == 0) + return trans->new_name; + return NULL; +} + static const char *config_translate_key (const char *key) { /* Returns translated key or, if no translation found, NULL. * Translated key may be in a static buffer allocated within this function. @@ -374,13 +374,11 @@ static const char *config_translate_key (const char *key) { } /* search the translation table... */ - for (trans = 0; - trans < sizeof(config_entry_translation) / sizeof(config_entry_translation[0]); - trans++) - if (config_entry_translation[trans].new[0] && strcmp(key, config_entry_translation[trans].old) == 0) - return config_entry_translation[trans].new; + newkey = config_xlate_internal (key, config_entry_translation); + if (!newkey && config_entry_translation_user) + newkey = config_xlate_internal (key, config_entry_translation_user); - return NULL; + return newkey; } static void config_lookup_entry_int (config_values_t *this, const char *key, @@ -906,6 +904,14 @@ static void config_update_string (config_values_t *this, } /* + * front end config translation handling + */ +void xine_config_set_translation_user (const xine_config_entry_translation_t *xlate) +{ + config_entry_translation_user = xlate; +} + +/* * load/save config data from/to afile (e.g. $HOME/.xine/config) */ void xine_config_load (xine_t *xine, const char *filename) { @@ -1063,7 +1069,7 @@ void xine_config_save (xine_t *xine, const char *filename) { if (!entry->key[0]) /* deleted key */ - continue; + goto next; lprintf ("saving key '%s'\n", entry->key); @@ -1133,6 +1139,7 @@ void xine_config_save (xine_t *xine, const char *filename) { break; } + next: entry = entry->next; } pthread_mutex_unlock(&this->config_lock); @@ -1334,7 +1341,7 @@ static char* config_get_serialized_entry (config_values_t *this, const char *key } /* and now the output encoding */ - output = base64_encode (buffer, total_len, &output_len); + output = xine_base64_encode (buffer, total_len, &output_len); free(buffer); } @@ -1350,7 +1357,7 @@ static int get_int(uint8_t *buffer, int buffer_size, int pos, int *value) { if ((pos + sizeof(int32_t)) > buffer_size) return 0; - value_int32 = LE_32(&buffer[pos]); + value_int32 = _X_LE_32(&buffer[pos]); *value = (int)value_int32; return sizeof(int32_t); } @@ -1406,7 +1413,7 @@ static char* config_register_serialized_entry (config_values_t *this, const char int value_count = 0; int i; - output = base64_decode (value, strlen(value), &output_len); + output = xine_base64_decode (value, strlen(value), &output_len); pos = 0; pos += bytes = get_int(output, output_len, pos, &type); diff --git a/src/xine-engine/configfile.h b/src/xine-engine/configfile.h deleted file mode 100644 index a4f4b34ec..000000000 --- a/src/xine-engine/configfile.h +++ /dev/null @@ -1,253 +0,0 @@ -/* - * Copyright (C) 2000-2004 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - * - * $Id: configfile.h,v 1.42 2007/02/22 15:49:16 dgp85 Exp $ - * - * config file management - * - */ - -#ifndef HAVE_CONFIGFILE_H -#define HAVE_CONFIGFILE_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include <pthread.h> - -#ifdef XINE_COMPILE -# include "xine.h" -#else -# include <xine.h> -#endif - -#define CONFIG_FILE_VERSION 2 - -/* - * config entries above this experience - * level must never be changed from MRL - */ -#define XINE_CONFIG_SECURITY 30 - - -typedef struct cfg_entry_s cfg_entry_t; -typedef struct config_values_s config_values_t; - - -struct cfg_entry_s { - cfg_entry_t *next; - config_values_t *config; - - char *key; - int type; - - /* type unknown */ - char *unknown_value; - - /* type string */ - char *str_value; - char *str_default; - - /* common to range, enum, num, bool: */ - - int num_value; - int num_default; - - /* type range specific: */ - int range_min; - int range_max; - - /* type enum specific: */ - char **enum_values; - - /* help info for the user */ - char *description; - char *help; - - /* user experience level */ - int exp_level; - - /* callback function and data for live changeable values */ - xine_config_cb_t callback; - void *callback_data; -}; - -struct config_values_s { - - /* - * register config values - * - * these functions return the current value of the - * registered item, i.e. the default value if it was - * not found in the config file or the current value - * from the config file otherwise - */ - - char* (*register_string) (config_values_t *self, - const char *key, - const char *def_value, - const char *description, - const char *help, - int exp_level, - xine_config_cb_t changed_cb, - void *cb_data); - - char* (*register_filename) (config_values_t *self, - const char *key, - const char *def_value, - int req_type, - const char *description, - const char *help, - int exp_level, - xine_config_cb_t changed_cb, - void *cb_data); - - int (*register_range) (config_values_t *self, - const char *key, - int def_value, - int min, int max, - const char *description, - const char *help, - int exp_level, - xine_config_cb_t changed_cb, - void *cb_data); - - int (*register_enum) (config_values_t *self, - const char *key, - int def_value, - char **values, - const char *description, - const char *help, - int exp_level, - xine_config_cb_t changed_cb, - void *cb_data); - - int (*register_num) (config_values_t *self, - const char *key, - int def_value, - const char *description, - const char *help, - int exp_level, - xine_config_cb_t changed_cb, - void *cb_data); - - int (*register_bool) (config_values_t *self, - const char *key, - int def_value, - const char *description, - const char *help, - int exp_level, - xine_config_cb_t changed_cb, - void *cb_data); - - void (*register_entry) (config_values_t *self, cfg_entry_t* entry); - - /* 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 */ - void (*update_string) (config_values_t *self, const char *key, const char *value); - - /* small utility function for enum handling */ - int (*parse_enum) (const char *str, const char **values); - - /* - * lookup config entries - * - * remember to call the changed_cb if it exists - * and you changed the value of this item - */ - - cfg_entry_t* (*lookup_entry) (config_values_t *self, const char *key); - - /* - * unregister entry 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); - - /* - * callback called when a new config entry is registered - */ - void (*set_new_entry_callback) (config_values_t *self, xine_config_cb_t new_entry_cb, void *cb_data); - - /* - * unregister the callback - */ - void (*unset_new_entry_callback) (config_values_t *self); - - /* - * serialize a config entry. - * return a base64 null terminated string. - */ - char* (*get_serialized_entry) (config_values_t *self, const char *key); - - /* - * deserialize a config entry. - * value is a base 64 encoded string - * return the key of the serialized entry - */ - char* (*register_serialized_entry) (config_values_t *self, const char *value); - - - /* - * config values are stored here: - */ - cfg_entry_t *first, *last, *cur; - - /* - * new entry callback - */ - xine_config_cb_t new_entry_cb; - void *new_entry_cbdata; - - /* - * 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 - */ -config_values_t *_x_config_init (void) XINE_PROTECTED; - -/* - * interpret stream_setup part of mrls for config value changes - */ - -int _x_config_change_opt(config_values_t *config, const char *opt) XINE_PROTECTED; - - -#ifdef __cplusplus -} -#endif - -#endif - diff --git a/src/xine-engine/demux.c b/src/xine-engine/demux.c index d1bd2bc1d..232e0342e 100644 --- a/src/xine-engine/demux.c +++ b/src/xine-engine/demux.c @@ -15,12 +15,10 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * Demuxer helper functions * hide some xine engine details from demuxers and reduce code duplication - * - * $Id: demux.c,v 1.66 2007/01/18 23:28:46 dgp85 Exp $ */ @@ -41,9 +39,9 @@ #define LOG */ -#include "xine_internal.h" -#include "demuxers/demux.h" -#include "buffer.h" +#include <xine/xine_internal.h> +#include <xine/demux.h> +#include <xine/buffer.h> #ifdef WIN32 #include <winsock.h> @@ -425,7 +423,7 @@ int _x_demux_stop_thread (xine_stream_t *stream) { return 0; } -int _x_demux_read_header( input_plugin_t *input, unsigned char *buffer, off_t size){ +int _x_demux_read_header( input_plugin_t *input, void *buffer, off_t size){ int read_size; unsigned char *buf; @@ -450,6 +448,11 @@ int _x_demux_read_header( input_plugin_t *input, unsigned char *buffer, off_t si int _x_demux_check_extension (const char *mrl, const char *extensions){ char *last_dot, *e, *ext_copy, *ext_work; + int found = 0; + + /* An empty extensions string means that the by-extension method can't + be used, so consider those cases as always passing. */ + if ( extensions == NULL ) return 1; ext_copy = strdup(extensions); ext_work = ext_copy; @@ -457,15 +460,23 @@ int _x_demux_check_extension (const char *mrl, const char *extensions){ last_dot = strrchr (mrl, '.'); if (last_dot) { last_dot++; - while ( ( e = xine_strsep(&ext_work, " ")) != NULL ) { + } + + while ( ( e = xine_strsep(&ext_work, " ")) != NULL ) { + if ( strstr(e, ":/") ) { + if ( strncasecmp (mrl, e, strlen (e)) == 0 ) { + found = 1; + break; + } + } else if (last_dot) { if (strcasecmp (last_dot, e) == 0) { - free(ext_copy); - return 1; + found = 1; + break; } } } free(ext_copy); - return 0; + return found; } diff --git a/src/xine-engine/events.c b/src/xine-engine/events.c index 990cbe787..bf0d88fae 100644 --- a/src/xine-engine/events.c +++ b/src/xine-engine/events.c @@ -15,12 +15,9 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - * - * $Id: events.c,v 1.32 2006/10/16 22:18:24 valtri Exp $ + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * Event handling functions - * */ #ifdef HAVE_CONFIG_H @@ -29,7 +26,7 @@ #define XINE_ENGINE_INTERNAL -#include "xine_internal.h" +#include <xine/xine_internal.h> xine_event_t *xine_event_get (xine_event_queue_t *queue) { diff --git a/src/xine-engine/info_helper.c b/src/xine-engine/info_helper.c index e38b5e5c4..bc66ba24e 100644 --- a/src/xine-engine/info_helper.c +++ b/src/xine-engine/info_helper.c @@ -15,12 +15,10 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * stream metainfo helper functions * hide some xine engine details from demuxers and reduce code duplication - * - * $Id: info_helper.c,v 1.19 2006/10/16 22:18:24 valtri Exp $ */ #ifdef HAVE_CONFIG_H @@ -37,7 +35,7 @@ #define XINE_ENGINE_INTERNAL -#include "info_helper.h" +#include <xine/info_helper.h> /* ******************* Stream Info *************************** */ diff --git a/src/xine-engine/info_helper.h b/src/xine-engine/info_helper.h deleted file mode 100644 index a21372e22..000000000 --- a/src/xine-engine/info_helper.h +++ /dev/null @@ -1,180 +0,0 @@ -/* - * Copyright (C) 2000-2003 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - * - * stream metainfo helper functions - * hide some xine engine details from demuxers and reduce code duplication - * - * $id$ - */ - -#ifndef INFO_HELPER_H -#define INFO_HELPER_H - -#include <stdarg.h> -#include "xine_internal.h" - -/* - * set a stream info - * - * params: - * *stream the xine stream - * info stream info id (see xine.h, XINE_STREAM_INFO_*) - * value the value to assign - * - */ -void _x_stream_info_set(xine_stream_t *stream, int info, int value) XINE_PROTECTED; - -/* - * reset a stream info (internal ones only) - * - * params : - * *stream the xine stream - * info meta info id (see xine.h, XINE_STREAM_INFO_*) - * - */ -void _x_stream_info_reset(xine_stream_t *stream, int info) XINE_PROTECTED; - -/* - * reset a stream info (public ones only) - * - * params : - * *stream the xine stream - * info meta info id (see xine.h, XINE_STREAM_INFO_*) - * - */ -void _x_stream_info_public_reset(xine_stream_t *stream, int info) XINE_PROTECTED; - -/* - * retrieve stream info (internal ones only) - * - * params : - * *stream the xine stream - * info meta info id (see xine.h, XINE_STREAM_INFO_*) - * - */ -uint32_t _x_stream_info_get(xine_stream_t *stream, int info) XINE_PROTECTED; - -/* - * retrieve stream info (public ones only) - * - * params : - * *stream the xine stream - * info meta info id (see xine.h, XINE_STREAM_INFO_*) - * - */ -uint32_t _x_stream_info_get_public(xine_stream_t *stream, int info) XINE_PROTECTED; - -/* - * set a stream meta info - * - * params: - * *stream the xine stream - * info meta info id (see xine.h, XINE_META_INFO_*) - * *str null-terminated string (using current locale) - * - */ -void _x_meta_info_set(xine_stream_t *stream, int info, const char *str) XINE_PROTECTED; - -/* - * set a stream meta info - * - * params: - * *stream the xine stream - * info meta info id (see xine.h, XINE_META_INFO_*) - * *str null-terminated string (using utf8) - * - */ -void _x_meta_info_set_utf8(xine_stream_t *stream, int info, const char *str) XINE_PROTECTED; - -/* - * set a stream meta info - * - * params: - * *stream the xine stream - * info meta info id (see xine.h, XINE_META_INFO_*) - * *str null-terminated string (using encoding below) - * *enc charset encoding of the string - * - */ -void _x_meta_info_set_generic(xine_stream_t *stream, int info, const char *str, const char *enc) XINE_PROTECTED; - -/* - * set a stream meta multiple info - * - * params: - * *stream the xine stream - * info meta info id (see xine.h, XINE_META_INFO_*) - * ... one or more meta info, followed by a NULL pointer - * - */ -void _x_meta_info_set_multi(xine_stream_t *stream, int info, ...) XINE_SENTINEL XINE_PROTECTED; - -/* - * set a stream meta info - * - * params: - * *stream the xine stream - * info meta info id (see xine.h, XINE_META_INFO_*) - * *buf char buffer (not a null-terminated string) - * len length of the metainfo - * - */ -void _x_meta_info_n_set(xine_stream_t *stream, int info, const char *buf, int len) XINE_PROTECTED; - -/* - * reset a stream meta info (internal ones only) - * - * params : - * *stream the xine stream - * info meta info id (see xine.h, XINE_META_INFO_*) - * - */ -void _x_meta_info_reset(xine_stream_t *stream, int info) XINE_PROTECTED; - -/* - * reset a stream meta info (public ones only) - * - * params : - * *stream the xine stream - * info meta info id (see xine.h, XINE_META_INFO_*) - * - */ -void _x_meta_info_public_reset(xine_stream_t *stream, int info) XINE_PROTECTED; - -/* - * retrieve stream meta info (internal ones only) - * - * params : - * *stream the xine stream - * info meta info id (see xine.h, XINE_META_INFO_*) - * - */ -const char *_x_meta_info_get(xine_stream_t *stream, int info) XINE_PROTECTED; - -/* - * retrieve stream meta info (public ones only) - * - * params : - * *stream the xine stream - * info meta info id (see xine.h, XINE_META_INFO_*) - * - */ -const char *_x_meta_info_get_public(xine_stream_t *stream, int info) XINE_PROTECTED; - -#endif /* INFO_HELPER_H */ diff --git a/src/xine-engine/input_cache.c b/src/xine-engine/input_cache.c index a566e1f84..2989d8718 100644 --- a/src/xine-engine/input_cache.c +++ b/src/xine-engine/input_cache.c @@ -15,14 +15,12 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * Buffered Input Plugin (request optimizer). * * The goal of this input plugin is to reduce * the number of calls to the real input plugin. - * - * $Id: input_cache.c,v 1.14 2007/02/20 00:34:57 dgp85 Exp $ */ #ifdef HAVE_CONFIG_H @@ -35,7 +33,8 @@ #define LOG */ -#include "xine_internal.h" +#include <xine/xine_internal.h> +#include <assert.h> #define DEFAULT_BUFFER_SIZE 1024 @@ -62,8 +61,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; @@ -74,7 +74,11 @@ static off_t cache_plugin_read(input_plugin_t *this_gen, char *buf, off_t len) { if (len <= (this->buf_len - this->buf_pos)) { /* all bytes are in the buffer */ switch (len) { -#if !(defined(sparc) || defined(__sparc__) || defined __ia64__) +#if defined(__i386__) || defined(__x86_64__) + /* These are restricted to x86 and amd64. Some other architectures don't + * handle unaligned accesses in the same way, quite possibly requiring + * extra code over and above simple byte copies. + */ case 8: *((uint64_t *)buf) = *(uint64_t *)(&(this->buf[this->buf_pos])); break; @@ -188,6 +192,7 @@ static buf_element_t *cache_plugin_read_block(input_plugin_t *this_gen, fifo_buf if (buf) { buf->type = BUF_DEMUX_BLOCK; + assert(todo <= buf->max_size); read_len = cache_plugin_read (this_gen, buf->content, todo); buf->size = read_len; } diff --git a/src/xine-engine/input_rip.c b/src/xine-engine/input_rip.c index 56850ba2d..e7ef356b3 100644 --- a/src/xine-engine/input_rip.c +++ b/src/xine-engine/input_rip.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * Rip Input Plugin for catching streams * @@ -28,8 +28,6 @@ * * - it's possible speeder saving streams in the xine without playing: * xine stream_mrl#save:file.raw\;noaudio\;novideo - * - * $Id: input_rip.c,v 1.34 2007/02/20 00:34:57 dgp85 Exp $ */ /* TODO: @@ -66,7 +64,7 @@ # define CLR_RST "\e[0;39m" #endif -#include "xine_internal.h" +#include <xine/xine_internal.h> #ifndef HAVE_FSEEKO # define fseeko fseek @@ -100,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/io_helper.c b/src/xine-engine/io_helper.c index ad36c565e..d51feb4c6 100644 --- a/src/xine-engine/io_helper.c +++ b/src/xine-engine/io_helper.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * abortable i/o helper functions */ @@ -38,7 +38,7 @@ #define XINE_ENGINE_INTERNAL -#include "io_helper.h" +#include <xine/io_helper.h> /* private constants */ #define XIO_FILE_READ 0 @@ -276,7 +276,7 @@ int _x_io_select (xine_stream_t *stream, int fd, int state, int timeout_msec) { wset = (state & XIO_WRITE_READY) ? &fdset : NULL; ret = select (fd + 1, rset, wset, NULL, &select_timeout); - if (ret == -1) { + if (ret == -1 && errno != EINTR) { /* select error */ return XIO_ERROR; } else if (ret == 1) { @@ -324,7 +324,8 @@ int _x_io_tcp_connect_finish(xine_stream_t *stream, int fd, int timeout_msec) { } -static off_t xio_rw_abort(xine_stream_t *stream, int fd, int cmd, char *buf, off_t todo) { +static off_t xio_rw_abort(xine_stream_t *stream, int fd, int cmd, void *buf_gen, off_t todo) { + uint8_t *buf = buf_gen; off_t ret = -1; off_t total = 0; @@ -411,19 +412,19 @@ static off_t xio_rw_abort(xine_stream_t *stream, int fd, int cmd, char *buf, off return total; } -off_t _x_io_tcp_read (xine_stream_t *stream, int s, char *buf, off_t todo) { +off_t _x_io_tcp_read (xine_stream_t *stream, int s, void *buf, off_t todo) { return xio_rw_abort (stream, s, XIO_TCP_READ, buf, todo); } -off_t _x_io_tcp_write (xine_stream_t *stream, int s, char *buf, off_t todo) { +off_t _x_io_tcp_write (xine_stream_t *stream, int s, void *buf, off_t todo) { return xio_rw_abort (stream, s, XIO_TCP_WRITE, buf, todo); } -off_t _x_io_file_read (xine_stream_t *stream, int s, char *buf, off_t todo) { +off_t _x_io_file_read (xine_stream_t *stream, int s, void *buf, off_t todo) { return xio_rw_abort (stream, s, XIO_FILE_READ, buf, todo); } -off_t _x_io_file_write (xine_stream_t *stream, int s, char *buf, off_t todo) { +off_t _x_io_file_write (xine_stream_t *stream, int s, void *buf, off_t todo) { return xio_rw_abort (stream, s, XIO_FILE_WRITE, buf, todo); } diff --git a/src/xine-engine/io_helper.h b/src/xine-engine/io_helper.h deleted file mode 100644 index 3b7cac17a..000000000 --- a/src/xine-engine/io_helper.h +++ /dev/null @@ -1,141 +0,0 @@ -/* - * Copyright (C) 2000-2003 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - * - * abortable i/o helper functions - */ - -#ifndef IO_HELPER_H -#define IO_HELPER_H - -#include "xine_internal.h" - - -/* select states */ -#define XIO_READ_READY 1 -#define XIO_WRITE_READY 2 - -/* xine select return codes */ -#define XIO_READY 0 -#define XIO_ERROR 1 -#define XIO_ABORTED 2 -#define XIO_TIMEOUT 3 - - -/* - * Waits for a file descriptor/socket to change status. - * - * network input plugins should use this function in order to - * not freeze the engine. - * - * params : - * stream needed for aborting and reporting errors but may be NULL - * fd file/socket descriptor - * state XIO_READ_READY, XIO_WRITE_READY - * timeout_sec timeout in seconds - * - * An other thread can abort this function if stream != NULL by setting - * stream->demux_action_pending. - * - * return value : - * XIO_READY the file descriptor is ready for cmd - * XIO_ERROR an i/o error occured - * XIO_ABORTED command aborted by an other thread - * XIO_TIMEOUT the file descriptor is not ready after timeout_msec milliseconds - */ -int _x_io_select (xine_stream_t *stream, int fd, int state, int timeout_msec) XINE_PROTECTED; - - -/* - * open a tcp connection - * - * params : - * stream needed for reporting errors but may be NULL - * host address of target - * port port on target - * - * returns a socket descriptor or -1 if an error occured - */ -int _x_io_tcp_connect(xine_stream_t *stream, const char *host, int port) XINE_PROTECTED; - -/* - * wait for finish connection - * - * params : - * stream needed for aborting and reporting errors but may be NULL - * fd socket descriptor - * timeout_msec timeout in milliseconds - * - * return value: - * XIO_READY host respond, the socket is ready for cmd - * XIO_ERROR an i/o error occured - * XIO_ABORTED command aborted by an other thread - * XIO_TIMEOUT the file descriptor is not ready after timeout - */ -int _x_io_tcp_connect_finish(xine_stream_t *stream, int fd, int timeout_msec) XINE_PROTECTED; - -/* - * read from tcp socket checking demux_action_pending - * - * network input plugins should use this function in order to - * not freeze the engine. - * - * aborts with zero if no data is available and *abort is set - */ -off_t _x_io_tcp_read (xine_stream_t *stream, int s, char *buf, off_t todo) XINE_PROTECTED; - - -/* - * write to a tcp socket checking demux_action_pending - * - * network input plugins should use this function in order to - * not freeze the engine. - * - * aborts with zero if no data is available and *abort is set - */ -off_t _x_io_tcp_write (xine_stream_t *stream, int s, char *buf, off_t todo) XINE_PROTECTED; - -/* - * read from a file descriptor checking demux_action_pending - * - * the fifo input plugin should use this function in order to - * not freeze the engine. - * - * aborts with zero if no data is available and *abort is set - */ -off_t _x_io_file_read (xine_stream_t *stream, int fd, char *buf, off_t todo) XINE_PROTECTED; - - -/* - * write to a file descriptor checking demux_action_pending - * - * the fifo input plugin should use this function in order to - * not freeze the engine. - * - * aborts with zero if *abort is set - */ -off_t _x_io_file_write (xine_stream_t *stream, int fd, char *buf, off_t todo) XINE_PROTECTED; - -/* - * read a string from socket, return string length (same as strlen) - * the string is always '\0' terminated but given buffer size is never exceeded - * that is, _x_io_tcp_read_line(,,,X) <= (X-1) ; X > 0 - */ -int _x_io_tcp_read_line(xine_stream_t *stream, int sock, char *str, int size) XINE_PROTECTED; - -#endif diff --git a/src/xine-engine/load_plugins.c b/src/xine-engine/load_plugins.c index f34b3bb66..94afc5b01 100644 --- a/src/xine-engine/load_plugins.c +++ b/src/xine-engine/load_plugins.c @@ -15,13 +15,10 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - * - * $Id: load_plugins.c,v 1.230 2007/02/19 23:33:33 dgp85 Exp $ + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * * Load input/demux/audio_out/video_out/codec plugins - * */ #ifdef HAVE_CONFIG_H @@ -43,6 +40,10 @@ #include <ctype.h> #include <signal.h> +#include <basedir.h> + +#include "load_plugins.h" + #define LOG_MODULE "load_plugins" #define LOG_VERBOSE @@ -53,17 +54,17 @@ #define XINE_ENABLE_EXPERIMENTAL_FEATURES 1 #define XINE_ENGINE_INTERNAL -#include "xine_internal.h" -#include "xine_plugin.h" -#include "plugin_catalog.h" -#include "demuxers/demux.h" -#include "input/input_plugin.h" -#include "video_out.h" -#include "post.h" -#include "metronom.h" -#include "configfile.h" -#include "xineutils.h" -#include "compat.h" +#include <xine/xine_internal.h> +#include <xine/xine_plugin.h> +#include <xine/plugin_catalog.h> +#include <xine/demux.h> +#include <xine/input_plugin.h> +#include <xine/video_out.h> +#include <xine/post.h> +#include <xine/metronom.h> +#include <xine/configfile.h> +#include <xine/xineutils.h> +#include <xine/compat.h> #define LINE_MAX_LENGTH (1024 * 32) /* 32 KiB */ @@ -98,8 +99,9 @@ static void remove_segv_handler(void){ #endif #endif /* 0 */ +#define CACHE_CATALOG_VERSION 3 -static int plugin_iface_versions[] = { +static const int plugin_iface_versions[] = { INPUT_PLUGIN_IFACE_VERSION, DEMUXER_PLUGIN_IFACE_VERSION, AUDIO_DECODER_IFACE_VERSION, @@ -156,7 +158,6 @@ static void dec_node_ref(plugin_node_t *node) { /* * plugin list/catalog management functions - * */ static int get_decoder_priority(xine_t *this, plugin_node_t *node) { @@ -321,7 +322,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); @@ -386,13 +386,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, @@ -1015,7 +1010,7 @@ static void load_plugin_list(xine_t *this, 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; @@ -1095,15 +1090,16 @@ static void load_plugin_list(xine_t *this, FILE *fp, xine_sarray_t *plugins) { vo_info->visual_type = i; } else if( !strcmp("supported_types",line) && decoder_info ) { char *s; + uint32_t *supported_types; 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)); - for( s = value, i = 0; s && sscanf(s," %lu",&lu) > 0; i++ ) { - decoder_info->supported_types[i] = lu; + supported_types = xine_xcalloc((i+1), sizeof(uint32_t)); + for( s = value, i = 0; s && sscanf(s," %"SCNu32,&supported_types[i]) > 0; i++ ) { s = strchr(s+1, ' '); } + decoder_info->supported_types = supported_types; } else if( !strcmp("vo_priority",line) && vo_info ) { sscanf(value," %d",&i); vo_info->priority = i; @@ -1144,27 +1140,68 @@ static void load_plugin_list(xine_t *this, FILE *fp, xine_sarray_t *plugins) { free (line); } +/** + * @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; @@ -1186,13 +1223,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 (this, fp, this->plugin_catalog->cache_list); fclose(fp); @@ -1301,12 +1334,11 @@ input_plugin_t *_x_find_input_plugin (xine_stream_t *stream, const char *mrl) { void _x_free_input_plugin (xine_stream_t *stream, input_plugin_t *input) { plugin_catalog_t *catalog = stream->xine->plugin_catalog; - plugin_node_t *node = input->node; input->dispose(input); - if (node) { + if (input->node) { pthread_mutex_lock(&catalog->lock); - dec_node_ref(node); + dec_node_ref(input->node); pthread_mutex_unlock(&catalog->lock); } } @@ -1346,6 +1378,12 @@ static demux_plugin_t *probe_demux (xine_stream_t *stream, int method1, int meth xprintf(stream->xine, XINE_VERBOSITY_DEBUG, "load_plugins: probing demux '%s'\n", node->info->id); if (node->plugin_class || _load_plugin_class(stream->xine, node, NULL)) { + if ( stream->content_detection_method == METHOD_BY_MRL && + ! _x_demux_check_extension(input->get_mrl(input), + ((demux_class_t *)node->plugin_class)->extensions) + ) + continue; + if ((plugin = ((demux_class_t *)node->plugin_class)->open_plugin(node->plugin_class, stream, input))) { inc_node_ref(node); plugin->node = node; @@ -1367,16 +1405,16 @@ demux_plugin_t *_x_find_demux_plugin (xine_stream_t *stream, input_plugin_t *inp switch (stream->xine->demux_strategy) { case XINE_DEMUX_DEFAULT_STRATEGY: - return probe_demux (stream, METHOD_BY_CONTENT, METHOD_BY_EXTENSION, input); + return probe_demux (stream, METHOD_BY_CONTENT, METHOD_BY_MRL, input); case XINE_DEMUX_REVERT_STRATEGY: - return probe_demux (stream, METHOD_BY_EXTENSION, METHOD_BY_CONTENT, input); + return probe_demux (stream, METHOD_BY_MRL, METHOD_BY_CONTENT, input); case XINE_DEMUX_CONTENT_STRATEGY: return probe_demux (stream, METHOD_BY_CONTENT, -1, input); case XINE_DEMUX_EXTENSION_STRATEGY: - return probe_demux (stream, METHOD_BY_EXTENSION, -1, input); + return probe_demux (stream, METHOD_BY_MRL, -1, input); default: xprintf (stream->xine, XINE_VERBOSITY_LOG, @@ -1405,6 +1443,13 @@ demux_plugin_t *_x_find_demux_plugin_by_name(xine_stream_t *stream, const char * if (strcasecmp(node->info->id, name) == 0) { if (node->plugin_class || _load_plugin_class(stream->xine, node, NULL)) { + + if ( stream->content_detection_method == METHOD_BY_MRL && + ! _x_demux_check_extension(input->get_mrl(input), + ((demux_class_t *)node->plugin_class)->extensions) + ) + continue; + if ((plugin = ((demux_class_t *)node->plugin_class)->open_plugin(node->plugin_class, stream, input))) { inc_node_ref(node); plugin->node = node; @@ -1437,7 +1482,7 @@ demux_plugin_t *_x_find_demux_plugin_last_probe(xine_stream_t *stream, const cha demux_plugin_t *plugin = NULL; methods[0] = METHOD_BY_CONTENT; - methods[1] = METHOD_BY_EXTENSION; + methods[1] = METHOD_BY_MRL; methods[2] = -1; i = 0; @@ -1462,6 +1507,14 @@ demux_plugin_t *_x_find_demux_plugin_last_probe(xine_stream_t *stream, const cha xprintf(stream->xine, XINE_VERBOSITY_DEBUG, "load_plugin: probing '%s' (method %d)...\n", node->info->id, stream->content_detection_method ); if (node->plugin_class || _load_plugin_class(xine, node, NULL)) { + + if ( stream->content_detection_method == METHOD_BY_MRL && + ! _x_demux_check_extension(input->get_mrl(input), + ((demux_class_t *)node->plugin_class)->extensions) + ) + continue; + + if ((plugin = ((demux_class_t *)node->plugin_class)->open_plugin(node->plugin_class, stream, input))) { xprintf (stream->xine, XINE_VERBOSITY_DEBUG, "load_plugins: using demuxer '%s' (instead of '%s')\n", node->info->id, last_demux_name); @@ -1502,12 +1555,11 @@ demux_plugin_t *_x_find_demux_plugin_last_probe(xine_stream_t *stream, const cha void _x_free_demux_plugin (xine_stream_t *stream, demux_plugin_t *demux) { plugin_catalog_t *catalog = stream->xine->plugin_catalog; - plugin_node_t *node = demux->node; demux->dispose(demux); - if (node) { + if (demux->node) { pthread_mutex_lock(&catalog->lock); - dec_node_ref(node); + dec_node_ref(demux->node); pthread_mutex_unlock(&catalog->lock); } } @@ -1685,7 +1737,7 @@ xine_video_port_t *xine_new_framegrab_video_port (xine_t *this) { xine_video_port_t *port; vo_info_t *vo_info; plugin_catalog_t *catalog = this->plugin_catalog; - char *id; + const char *id; int list_id, list_size; driver = NULL; @@ -1759,6 +1811,38 @@ static ao_driver_t *_load_audio_driver (xine_t *this, plugin_node_t *node, return driver; } +ao_driver_t *_x_load_audio_output_plugin (xine_t *this, const char *id) +{ + plugin_node_t *node; + ao_driver_t *driver = NULL; + ao_info_t *ao_info; + plugin_catalog_t *catalog = this->plugin_catalog; + int list_id, list_size; + + pthread_mutex_lock (&catalog->lock); + + list_size = xine_sarray_size (this->plugin_catalog->plugin_lists[PLUGIN_AUDIO_OUT - 1]); + for (list_id = 0; list_id < list_size; list_id++) { + + node = xine_sarray_get (this->plugin_catalog->plugin_lists[PLUGIN_AUDIO_OUT - 1], list_id); + + ao_info = (ao_info_t *)node->info->special_info; + + if (!strcasecmp(node->info->id, id)) { + driver = _load_audio_driver (this, node, NULL); + break; + } + } + + pthread_mutex_unlock (&catalog->lock); + + if (!driver) { + xprintf (this, XINE_VERBOSITY_LOG, + _("load_plugins: failed to load audio output plugin <%s>\n"), id); + } + return driver; +} + xine_audio_port_t *xine_open_audio_driver (xine_t *this, const char *id, void *data) { @@ -1965,13 +2049,12 @@ video_decoder_t *_x_get_video_decoder (xine_stream_t *stream, uint8_t stream_typ void _x_free_video_decoder (xine_stream_t *stream, video_decoder_t *vd) { plugin_catalog_t *catalog = stream->xine->plugin_catalog; - plugin_node_t *node = vd->node; vd->dispose (vd); - if (node) { + if (vd->node) { pthread_mutex_lock (&catalog->lock); - dec_node_ref(node); + dec_node_ref(vd->node); pthread_mutex_unlock (&catalog->lock); } } @@ -2277,7 +2360,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; @@ -2315,7 +2398,7 @@ const char *const *xine_list_post_plugins_typed(xine_t *xine, int type) { else \ return NULL; \ } \ - return ic->get_description(ic); \ + return dgettext(ic->textdomain ? : XINE_TEXTDOMAIN, ic->description); \ } \ } \ return NULL; \ @@ -2445,6 +2528,7 @@ char *xine_get_file_extensions (xine_t *self) { plugin_node_t *node; char *str; int list_id, list_size; + const char *exts; pthread_mutex_lock (&catalog->lock); @@ -2454,14 +2538,13 @@ char *xine_get_file_extensions (xine_t *self) { list_size = xine_sarray_size (catalog->plugin_lists[PLUGIN_DEMUX - 1]); for (list_id = 0; list_id < list_size; list_id++) { demux_class_t *cls; - const char *exts; node = xine_sarray_get (catalog->plugin_lists[PLUGIN_DEMUX - 1], list_id); if (node->plugin_class || _load_plugin_class(self, node, NULL)) { cls = (demux_class_t *)node->plugin_class; - if((exts = cls->get_extensions(cls)) && *exts) + if( (exts = cls->extensions) && *exts ) len += strlen(exts) + 1; } } @@ -2473,7 +2556,6 @@ char *xine_get_file_extensions (xine_t *self) { list_size = xine_sarray_size (catalog->plugin_lists[PLUGIN_DEMUX - 1]); for (list_id = 0; list_id < list_size; list_id++) { demux_class_t *cls; - const char *e; int l; node = xine_sarray_get (catalog->plugin_lists[PLUGIN_DEMUX - 1], list_id); @@ -2481,9 +2563,9 @@ char *xine_get_file_extensions (xine_t *self) { cls = (demux_class_t *)node->plugin_class; - if((e = cls->get_extensions (cls)) && *e) { - l = strlen(e); - memcpy (&str[pos], e, l); + if((exts = cls->extensions) && *exts) { + l = strlen(exts); + memcpy (&str[pos], exts, l); pos += l; @@ -2523,16 +2605,14 @@ char *xine_get_mime_types (xine_t *self) { for (list_id = 0; list_id < list_size; list_id++) { demux_class_t *cls; - const char *s; node = xine_sarray_get (catalog->plugin_lists[PLUGIN_DEMUX - 1], list_id); if (node->plugin_class || _load_plugin_class(self, node, NULL)) { cls = (demux_class_t *)node->plugin_class; - s = cls->get_mimetypes (cls); - if (s) - len += strlen(s); + if ( cls->mimetypes ) + len += strlen(cls->mimetypes); } } @@ -2545,18 +2625,15 @@ char *xine_get_mime_types (xine_t *self) { for (list_id = 0; list_id < list_size; list_id++) { demux_class_t *cls; - const char *s; - int l; node = xine_sarray_get (catalog->plugin_lists[PLUGIN_DEMUX - 1], list_id); if (node->plugin_class || _load_plugin_class(self, node, NULL)) { cls = (demux_class_t *)node->plugin_class; - s = cls->get_mimetypes (cls); - if (s) { - l = strlen(s); - memcpy (&str[pos], s, l); + if (cls->mimetypes) { + const size_t l = strlen(cls->mimetypes); + memcpy (&str[pos], cls->mimetypes, l); pos += l; } @@ -2580,16 +2657,8 @@ char *xine_get_demux_for_mime_type (xine_t *self, const char *mime_type) { plugin_catalog_t *catalog = self->plugin_catalog; plugin_node_t *node; char *id = NULL; - char *mime_arg, *mime_demux; - char *s; - const char *mt; int list_id, list_size; - /* create a copy and convert to lower case */ - mime_arg = strdup(mime_type); - for(s=mime_arg; *s; s++) - *s = tolower(*s); - pthread_mutex_lock (&catalog->lock); list_size = xine_sarray_size (catalog->plugin_lists[PLUGIN_DEMUX - 1]); @@ -2601,26 +2670,14 @@ char *xine_get_demux_for_mime_type (xine_t *self, const char *mime_type) { if (node->plugin_class || _load_plugin_class(self, node, NULL)) { cls = (demux_class_t *)node->plugin_class; - - mt = cls->get_mimetypes (cls); - if (mt) { - mime_demux = strdup(mt); - for(s=mime_demux; *s; s++) - *s = tolower(*s); - - if( strstr(mime_demux, mime_arg) ) + if (cls->mimetypes && strcasestr(cls->mimetypes, mime_type) ) id = strdup(node->info->id); - - free(mime_demux); - } } } pthread_mutex_unlock (&catalog->lock); - free(mime_arg); - return id; } diff --git a/src/xine-engine/load_plugins.h b/src/xine-engine/load_plugins.h new file mode 100644 index 000000000..7e7d3cc93 --- /dev/null +++ b/src/xine-engine/load_plugins.h @@ -0,0 +1,50 @@ +/* + * 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, USA + */ + +/** + * @file + * @brief Internal functions related to the plugin catalog. + * + * @internal This code should not be used by plugins or frontends, it's only + * used by the xine-engine. + */ + +#ifndef __LOAD_PLUGINS_H__ +#define __LOAD_PLUGINS_H__ + +#include <xine.h> + +/* + * load plugins into catalog + * + * all input+demux plugins will be fully loaded+initialized + * decoder plugins are loaded on demand + * video/audio output plugins have special load/probe functions + */ +void _x_scan_plugins (xine_t *this); + + +/* + * dispose all currently loaded plugins (shutdown) + */ + +void _x_dispose_plugins (xine_t *this); + +#endif diff --git a/src/xine-engine/lrb.c b/src/xine-engine/lrb.c index 87465aaef..a2fc5d1da 100644 --- a/src/xine-engine/lrb.c +++ b/src/xine-engine/lrb.c @@ -15,10 +15,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - * - * $Id: lrb.c,v 1.8 2003/12/09 00:02:36 f1rmb Exp $ - * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ #ifdef HAVE_CONFIG_H @@ -26,7 +23,7 @@ #endif #include "lrb.h" -#include "xineutils.h" +#include <xine/xineutils.h> lrb_t *lrb_new (int max_num_entries, fifo_buffer_t *fifo) { diff --git a/src/xine-engine/lrb.h b/src/xine-engine/lrb.h index 1b53ed929..0f524b7eb 100644 --- a/src/xine-engine/lrb.h +++ b/src/xine-engine/lrb.h @@ -15,23 +15,16 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - * - * $Id: lrb.h,v 1.4 2003/12/09 00:02:36 f1rmb Exp $ + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * lrb : limited ring buffer * used for temporal buffer, limited to n elements - * */ #ifndef HAVE_LRB_H #define HAVE_LRB_H -#ifdef XINE_COMPILE -# include "buffer.h" -#else -# include <xine/buffer.h> -#endif +#include <xine/buffer.h> typedef struct { diff --git a/src/xine-engine/metronom.c b/src/xine-engine/metronom.c index fa33da9e1..42aed4e76 100644 --- a/src/xine-engine/metronom.c +++ b/src/xine-engine/metronom.c @@ -15,9 +15,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - * - * $Id: metronom.c,v 1.144 2007/02/20 00:34:57 dgp85 Exp $ + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ #ifdef HAVE_CONFIG_H @@ -42,9 +40,9 @@ #define METRONOM_INTERNAL #define METRONOM_CLOCK_INTERNAL -#include "xine_internal.h" -#include "metronom.h" -#include "xineutils.h" +#include <xine/xine_internal.h> +#include <xine/metronom.h> +#include <xine/xineutils.h> #define MAX_AUDIO_DELTA 1600 #define AUDIO_SAMPLE_NUM 32768 @@ -178,7 +176,6 @@ static scr_plugin_t* unixscr_init () { unixscr_t *this; this = (unixscr_t *) xine_xmalloc(sizeof(unixscr_t)); - memset(this, 0, sizeof(*this)); this->scr.interface_version = 3; this->scr.get_priority = unixscr_get_priority; @@ -851,7 +848,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; @@ -874,7 +872,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) { @@ -990,7 +988,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 deleted file mode 100644 index 1628ba9fd..000000000 --- a/src/xine-engine/metronom.h +++ /dev/null @@ -1,367 +0,0 @@ -/* - * Copyright (C) 2000-2004 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - * - * $Id: metronom.h,v 1.64 2006/09/26 05:19:49 dgp85 Exp $ - * - * metronom: general pts => virtual calculation/assoc - * - * virtual pts: unit 1/90000 sec, always increasing - * can be used for synchronization - * video/audio frame with same pts also have same vpts - * but pts is likely to differ from vpts - * - * the basic idea is: - * video_pts + video_wrap_offset = video_vpts - * audio_pts + audio_wrap_offset = audio_vpts - * - * - video_wrap_offset should be equal to audio_wrap_offset as to have - * perfect audio and video sync. They will differ on brief periods due - * discontinuity correction. - * - metronom should also interpolate vpts values most of the time as - * video_pts and audio_vpts are not given for every frame. - * - corrections to the frame rate may be needed to cope with bad - * encoded streams. - * - */ - -#ifndef HAVE_METRONOM_H -#define HAVE_METRONOM_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include <pthread.h> - -#ifdef XINE_COMPILE -# include "video_out.h" -# include "xine.h" -#else -# include <xine/video_out.h> -# include <xine.h> -#endif - -typedef struct metronom_s metronom_t ; -typedef struct metronom_clock_s metronom_clock_t; -typedef struct scr_plugin_s scr_plugin_t; - -/* metronom prebuffer can be adjusted with XINE_PARAM_METRONOM_PREBUFFER. - * it sets how much the first video/audio frame should be delayed to - * have some prebuffering at the output layers. reducing this value (about - * 1/8 sec) may result in faster seeking (good to simulate play backwards, - * for example). - */ -#define PREBUFFER_PTS_OFFSET 12000 - - /* see below */ -#define DISC_STREAMSTART 0 -#define DISC_RELATIVE 1 -#define DISC_ABSOLUTE 2 -#define DISC_STREAMSEEK 3 - -struct metronom_s { - - /* - * called by audio output driver to inform metronom about current audio - * samplerate - * - * parameter pts_per_smpls : 1/90000 sec per 65536 samples - */ - void (*set_audio_rate) (metronom_t *self, int64_t pts_per_smpls); - - /* - * called by video output driver for *every* frame - * - * parameter frame containing pts, scr, ... information - * - * will set vpts field in frame - * - * this function will also update video_wrap_offset if a discontinuity - * is detected (read the comentaries below about discontinuities). - * - */ - - void (*got_video_frame) (metronom_t *self, vo_frame_t *frame); - - /* - * called by audio output driver whenever audio samples are delivered to it - * - * parameter pts : pts for audio data if known, 0 otherwise - * nsamples : number of samples delivered - * - * return value: virtual pts for audio data - * - * this function will also update audio_wrap_offset if a discontinuity - * is detected (read the comentaries below about discontinuities). - * - */ - - int64_t (*got_audio_samples) (metronom_t *self, int64_t pts, - int nsamples); - - /* - * called by SPU decoder whenever a packet is delivered to it - * - * parameter pts : pts for SPU packet if known, 0 otherwise - * - * return value: virtual pts for SPU packet - * (this is the only pts to vpts function that cannot update the wrap_offset - * due to the lack of regularity on spu packets) - */ - - int64_t (*got_spu_packet) (metronom_t *self, int64_t pts); - - /* - * tell metronom about discontinuities. - * - * these functions are called due to a discontinuity detected at - * demux stage. - * - * there are different types of discontinuities: - * - * DISC_STREAMSTART : new stream starts, expect pts values to start - * from zero immediately - * DISC_RELATIVE : typically a wrap-around, expect pts with - * a specified offset from the former ones soon - * DISC_ABSOLUTE : typically a new menu stream (nav packets) - * pts will start from given value soon - * DISC_STREAMSEEK : used by video and audio decoder loop, - * when a buffer with BUF_FLAG_SEEK set is encountered; - * applies the necessary vpts offset for the seek in - * metronom, but keeps the vpts difference between - * audio and video, so that metronom doesn't cough - */ - void (*handle_audio_discontinuity) (metronom_t *self, int type, int64_t disc_off); - void (*handle_video_discontinuity) (metronom_t *self, int type, int64_t disc_off); - - /* - * set/get options for metronom, constants see below - */ - void (*set_option) (metronom_t *self, int option, int64_t value); - int64_t (*get_option) (metronom_t *self, int option); - - /* - * set a master metronom - * this is currently useful to sync independently generated streams - * (e.g. by post plugins) to the discontinuity domain of another - * metronom - */ - void (*set_master) (metronom_t *self, metronom_t *master); - - void (*exit) (metronom_t *self); - -#ifdef METRONOM_INTERNAL - /* - * metronom internal stuff - */ - xine_t *xine; - - metronom_t *master; - - int64_t pts_per_smpls; - - int64_t video_vpts; - int64_t spu_vpts; - int64_t audio_vpts; - int64_t audio_vpts_rmndr; /* the remainder for integer division */ - - int64_t vpts_offset; - - int64_t video_drift; - int64_t video_drift_step; - - int audio_samples; - int64_t audio_drift_step; - - int64_t prebuffer; - int64_t av_offset; - int64_t spu_offset; - - pthread_mutex_t lock; - - int have_video; - int have_audio; - int video_discontinuity_count; - int audio_discontinuity_count; - int discontinuity_handled_count; - pthread_cond_t video_discontinuity_reached; - pthread_cond_t audio_discontinuity_reached; - - int force_video_jump; - int force_audio_jump; - - int64_t img_duration; - int img_cpt; - int64_t last_video_pts; - int64_t last_audio_pts; - - int video_mode; -#endif -}; - -/* - * metronom options - */ - -#define METRONOM_AV_OFFSET 2 -#define METRONOM_ADJ_VPTS_OFFSET 3 -#define METRONOM_FRAME_DURATION 4 -#define METRONOM_SPU_OFFSET 5 -#define METRONOM_VPTS_OFFSET 6 -#define METRONOM_PREBUFFER 7 - -metronom_t *_x_metronom_init (int have_video, int have_audio, xine_t *xine) XINE_PROTECTED; - -/* FIXME: reorder this structure on the next cleanup to remove the dummies */ -struct metronom_clock_s { - - /* - * set/get options for clock, constants see below - */ - void (*set_option) (metronom_clock_t *self, int option, int64_t value); - int64_t (*get_option) (metronom_clock_t *self, int option); - - /* - * system clock reference (SCR) functions - */ - -#ifdef METRONOM_CLOCK_INTERNAL - /* - * start clock (no clock reset) - * at given pts - */ - void (*start_clock) (metronom_clock_t *self, int64_t pts); - - - /* - * stop metronom clock - */ - void (*stop_clock) (metronom_clock_t *self); - - - /* - * resume clock from where it was stopped - */ - void (*resume_clock) (metronom_clock_t *self); -#else - void *dummy1; - void *dummy2; - void *dummy3; -#endif - - - /* - * get current clock value in vpts - */ - int64_t (*get_current_time) (metronom_clock_t *self); - - - /* - * adjust master clock to external timer (e.g. audio hardware) - */ - void (*adjust_clock) (metronom_clock_t *self, int64_t desired_pts); - -#ifdef METRONOM_CLOCK_INTERNAL - /* - * set clock speed - * for constants see xine_internal.h - */ - - int (*set_fine_speed) (metronom_clock_t *self, int speed); -#else - void *dummy4; -#endif - - /* - * (un)register a System Clock Reference provider at the metronom - */ - int (*register_scr) (metronom_clock_t *self, scr_plugin_t *scr); - void (*unregister_scr) (metronom_clock_t *self, scr_plugin_t *scr); - -#ifdef METRONOM_CLOCK_INTERNAL - void (*exit) (metronom_clock_t *self); - - xine_t *xine; - - scr_plugin_t *scr_master; - scr_plugin_t **scr_list; - pthread_t sync_thread; - int thread_running; - int scr_adjustable; -#else - void *dummy5; - void *dummy6; - void *dummy7; - void *dummy8; - pthread_t dummy9; - int dummy10; - int dummy11; -#endif - - int speed; - -#ifdef METRONOM_CLOCK_INTERNAL - pthread_mutex_t lock; - pthread_cond_t cancel; -#endif -}; - -metronom_clock_t *_x_metronom_clock_init(xine_t *xine) XINE_PROTECTED; - -/* - * clock options - */ - -#define CLOCK_SCR_ADJUSTABLE 1 - -/* - * SCR (system clock reference) plugins - */ - -struct scr_plugin_s -{ - int interface_version; - - int (*get_priority) (scr_plugin_t *self); - - /* - * set/get clock speed - * - * for speed constants see xine_internal.h - * returns actual speed - */ - - int (*set_fine_speed) (scr_plugin_t *self, int speed); - - void (*adjust) (scr_plugin_t *self, int64_t vpts); - - void (*start) (scr_plugin_t *self, int64_t start_vpts); - - int64_t (*get_current) (scr_plugin_t *self); - - void (*exit) (scr_plugin_t *self); - - metronom_clock_t *clock; -}; - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/xine-engine/osd.c b/src/xine-engine/osd.c index b68b3b5c2..907b20c8e 100644 --- a/src/xine-engine/osd.c +++ b/src/xine-engine/osd.c @@ -15,13 +15,11 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * OSD stuff (text and graphic primitives) */ -#define __OSD_C__ - #ifdef HAVE_CONFIG_H #include "config.h" #endif @@ -40,6 +38,8 @@ # include <iconv.h> #endif +#include <basedir.h> + #define LOG_MODULE "osd" #define LOG_VERBOSE /* @@ -48,11 +48,11 @@ #define XINE_ENGINE_INTERNAL -#include "xine_internal.h" +#include <xine/xine_internal.h> #include "xine-engine/bswap.h" -#include "xineutils.h" -#include "video_out.h" -#include "osd.h" +#include <xine/xineutils.h> +#include <xine/video_out.h> +#include <xine/osd.h> #ifdef HAVE_FT2 #include <ft2build.h> @@ -108,6 +108,100 @@ # define FT_LOAD_FLAGS (FT_LOAD_DEFAULT | FT_LOAD_NO_HINTING) #endif +/* This text descriptions are used for config screen */ +static const char *const textpalettes_str[NUMBER_OF_TEXT_PALETTES+1] = { + "white-black-transparent", + "white-none-transparent", + "white-none-translucid", + "yellow-black-transparent", + NULL}; + +/* + Palette entries as used by osd fonts: + + 0: not used by font, always transparent + 1: font background, usually transparent, may be used to implement + translucid boxes where the font will be printed. + 2-5: transition between background and border (usually only alpha + value changes). + 6: font border. if the font is to be displayed without border this + will probably be adjusted to font background or near. + 7-9: transition between border and foreground + 10: font color (foreground) +*/ + +/* + The palettes below were made by hand, ie, i just throw + values that seemed to do the transitions i wanted. + This can surelly be improved a lot. [Miguel] +*/ + +static const clut_t textpalettes_color[NUMBER_OF_TEXT_PALETTES][TEXT_PALETTE_SIZE] = { +/* white, black border, transparent */ + { + CLUT_Y_CR_CB_INIT(0x00, 0x00, 0x00), /*0*/ + CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), /*1*/ + CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), /*2*/ + CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), /*3*/ + CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), /*4*/ + CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), /*5*/ + CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), /*6*/ + CLUT_Y_CR_CB_INIT(0x40, 0x80, 0x80), /*7*/ + CLUT_Y_CR_CB_INIT(0x80, 0x80, 0x80), /*8*/ + CLUT_Y_CR_CB_INIT(0xc0, 0x80, 0x80), /*9*/ + CLUT_Y_CR_CB_INIT(0xff, 0x80, 0x80), /*10*/ + }, + /* white, no border, transparent */ + { + CLUT_Y_CR_CB_INIT(0x00, 0x00, 0x00), /*0*/ + CLUT_Y_CR_CB_INIT(0xff, 0x80, 0x80), /*1*/ + CLUT_Y_CR_CB_INIT(0xff, 0x80, 0x80), /*2*/ + CLUT_Y_CR_CB_INIT(0xff, 0x80, 0x80), /*3*/ + CLUT_Y_CR_CB_INIT(0xff, 0x80, 0x80), /*4*/ + CLUT_Y_CR_CB_INIT(0xff, 0x80, 0x80), /*5*/ + CLUT_Y_CR_CB_INIT(0xff, 0x80, 0x80), /*6*/ + CLUT_Y_CR_CB_INIT(0xff, 0x80, 0x80), /*7*/ + CLUT_Y_CR_CB_INIT(0xff, 0x80, 0x80), /*8*/ + CLUT_Y_CR_CB_INIT(0xff, 0x80, 0x80), /*9*/ + CLUT_Y_CR_CB_INIT(0xff, 0x80, 0x80), /*10*/ + }, + /* white, no border, translucid */ + { + CLUT_Y_CR_CB_INIT(0x00, 0x00, 0x00), /*0*/ + CLUT_Y_CR_CB_INIT(0x80, 0x80, 0x80), /*1*/ + CLUT_Y_CR_CB_INIT(0x80, 0x80, 0x80), /*2*/ + CLUT_Y_CR_CB_INIT(0x80, 0x80, 0x80), /*3*/ + CLUT_Y_CR_CB_INIT(0x80, 0x80, 0x80), /*4*/ + CLUT_Y_CR_CB_INIT(0x80, 0x80, 0x80), /*5*/ + CLUT_Y_CR_CB_INIT(0x80, 0x80, 0x80), /*6*/ + CLUT_Y_CR_CB_INIT(0xa0, 0x80, 0x80), /*7*/ + CLUT_Y_CR_CB_INIT(0xc0, 0x80, 0x80), /*8*/ + CLUT_Y_CR_CB_INIT(0xe0, 0x80, 0x80), /*9*/ + CLUT_Y_CR_CB_INIT(0xff, 0x80, 0x80), /*10*/ + }, + /* yellow, black border, transparent */ + { + CLUT_Y_CR_CB_INIT(0x00, 0x00, 0x00), /*0*/ + CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), /*1*/ + CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), /*2*/ + CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), /*3*/ + CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), /*4*/ + CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), /*5*/ + CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), /*6*/ + CLUT_Y_CR_CB_INIT(0x40, 0x84, 0x60), /*7*/ + CLUT_Y_CR_CB_INIT(0x70, 0x88, 0x40), /*8*/ + CLUT_Y_CR_CB_INIT(0xb0, 0x8a, 0x20), /*9*/ + CLUT_Y_CR_CB_INIT(0xff, 0x90, 0x00), /*10*/ + }, +}; + +static const uint8_t textpalettes_trans[NUMBER_OF_TEXT_PALETTES][TEXT_PALETTE_SIZE] = { + {0, 0, 3, 6, 8, 10, 12, 14, 15, 15, 15 }, + {0, 0, 0, 0, 0, 0, 2, 6, 9, 12, 15 }, + {0, 8, 9, 10, 11, 12, 13, 14, 15, 15, 15 }, + {0, 0, 3, 6, 8, 10, 12, 14, 15, 15, 15 }, +}; + typedef struct osd_fontchar_s { uint8_t *bmp; uint16_t code; @@ -197,7 +291,7 @@ static int _osd_show (osd_object_t *osd, int64_t vpts, int unscaled ) { osd_renderer_t *this = osd->renderer; video_overlay_manager_t *ovl_manager; rle_elem_t rle, *rle_p=0; - int x, y, required; + int x, y; uint8_t *c; lprintf("osd=%p vpts=%"PRId64"\n", osd, vpts); @@ -251,11 +345,11 @@ static int _osd_show (osd_object_t *osd, int64_t vpts, int unscaled ) { this->event.object.overlay->hili_right = this->event.object.overlay->width; /* there will be at least that many rle objects (one for each row) */ - required = osd->y2 - osd->y1; this->event.object.overlay->num_rle = 0; - this->event.object.overlay->data_size = 1024; - while (required > this->event.object.overlay->data_size) - this->event.object.overlay->data_size += 1024; + /* We will never need more rle objects than columns in any row + Rely on lazy page allocation to avoid us actually taking up + this much RAM */ + this->event.object.overlay->data_size = osd->width * osd->height; rle_p = this->event.object.overlay->rle = malloc(this->event.object.overlay->data_size * sizeof(rle_elem_t) ); @@ -272,14 +366,6 @@ static int _osd_show (osd_object_t *osd, int64_t vpts, int unscaled ) { /* loop over the remaining pixels in the row */ for( x = osd->x1 + rle.len; x < osd->x2; x++, c++ ) { if( rle.color != *c ) { - if( (this->event.object.overlay->num_rle + required) > - this->event.object.overlay->data_size ) { - this->event.object.overlay->data_size += 1024; - rle_p = this->event.object.overlay->rle = - realloc( this->event.object.overlay->rle, - this->event.object.overlay->data_size * sizeof(rle_elem_t) ); - rle_p += this->event.object.overlay->num_rle; - } #ifdef DEBUG_RLE lprintf("(%d, %d), ", rle.len, rle.color); #endif @@ -297,8 +383,6 @@ static int _osd_show (osd_object_t *osd, int64_t vpts, int unscaled ) { #endif *rle_p++ = rle; this->event.object.overlay->num_rle++; - /* another row done */ - required--; } #ifdef DEBUG_RLE lprintf("osd_show %p rle ends\n", osd); @@ -826,6 +910,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)); @@ -838,68 +1009,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")); @@ -1005,7 +1127,7 @@ static int osd_search(osd_fontchar_t *array, size_t n, uint16_t code) { * get next unicode value */ static uint16_t osd_iconv_getunicode(xine_t *xine, - iconv_t *cd, const char *encoding, ICONV_CONST char **inbuf, + iconv_t cd, const char *encoding, ICONV_CONST char **inbuf, size_t *inbytesleft) { uint16_t unicode; char *outbuf = (char*)&unicode; @@ -1587,7 +1709,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; @@ -1598,12 +1719,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 deleted file mode 100644 index 6c7be8f0b..000000000 --- a/src/xine-engine/osd.h +++ /dev/null @@ -1,366 +0,0 @@ -/* - * Copyright (C) 2000-2003 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - * - * OSD stuff (text and graphic primitives) - * $Id: osd.h,v 1.27 2006/09/26 05:19:49 dgp85 Exp $ - */ - -#ifndef HAVE_OSD_H -#define HAVE_OSD_H - -#ifdef HAVE_ICONV -# include <iconv.h> -#endif - -#ifdef XINE_COMPILE -# include "video_overlay.h" -# ifdef __OSD_C__ -# include "alphablend.h" -# endif -#else -# include <xine/video_overlay.h> -#endif - -typedef struct osd_object_s osd_object_t; -typedef struct osd_renderer_s osd_renderer_t; -typedef struct osd_font_s osd_font_t; -typedef struct osd_ft2context_s osd_ft2context_t; - -struct osd_object_s { - osd_object_t *next; - osd_renderer_t *renderer; - - int width, height; /* work area dimentions */ - uint8_t *area; /* work area */ - int display_x,display_y; /* where to display it in screen */ - - /* clipping box inside work area */ - int x1, y1; - int x2, y2; - - 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 */ -#endif - - osd_font_t *font; - osd_ft2context_t *ft2; -}; - -/* this one is public */ -struct xine_osd_s { - osd_object_t osd; -}; - -struct osd_renderer_s { - - /* - * open a new osd object. this will allocated an empty (all zero) drawing - * area where graphic primitives may be used. - * It is ok to specify big width and height values. The render will keep - * track of the smallest changed area to not generate too big overlays. - * A default palette is initialized (i sugest keeping color 0 as transparent - * for the sake of simplicity) - */ - osd_object_t* (*new_object) (osd_renderer_t *this, int width, int height); - - /* - * free osd object - */ - void (*free_object) (osd_object_t *osd_to_close); - - - /* - * send the osd to be displayed at given pts (0=now) - * the object is not changed. there may be subsequent drawing on it. - */ - int (*show) (osd_object_t *osd, int64_t vpts ); - - /* - * send event to hide osd at given pts (0=now) - * the object is not changed. there may be subsequent drawing on it. - */ - int (*hide) (osd_object_t *osd, int64_t vpts ); - - /* - * draw point. - */ - void (*point) (osd_object_t *osd, int x, int y, int color); - - /* - * Bresenham line implementation on osd object - */ - void (*line) (osd_object_t *osd, - int x1, int y1, int x2, int y2, int color ); - - /* - * filled rectangle - */ - void (*filled_rect) (osd_object_t *osd, - int x1, int y1, int x2, int y2, int color ); - - /* - * set palette (color and transparency) - */ - void (*set_palette) (osd_object_t *osd, const uint32_t *color, const uint8_t *trans ); - - /* - * set on existing text palette - * (-1 to set used specified palette) - * - * color_base specifies the first color index to use for this text - * palette. The OSD palette is then modified starting at this - * color index, up to the size of the text palette. - * - * Use OSD_TEXT1, OSD_TEXT2, ... for some preasssigned color indices. - */ - void (*set_text_palette) (osd_object_t *osd, int palette_number, - int color_base ); - - /* - * get palette (color and transparency) - */ - void (*get_palette) (osd_object_t *osd, uint32_t *color, - uint8_t *trans); - - /* - * set position were overlay will be blended - */ - void (*set_position) (osd_object_t *osd, int x, int y); - - /* - * set the font of osd object - */ - - int (*set_font) (osd_object_t *osd, const char *fontname, int size); - - /* - * set encoding of text - * - * NULL ... no conversion (iso-8859-1) - * "" ... locale encoding - */ - int (*set_encoding) (osd_object_t *osd, const char *encoding); - - /* - * render text in current encoding on x,y position - * no \n yet - * - * The text is assigned the colors starting at the index specified by - * color_base up to the size of the text palette. - * - * Use OSD_TEXT1, OSD_TEXT2, ... for some preasssigned color indices. - */ - int (*render_text) (osd_object_t *osd, int x1, int y1, - const char *text, int color_base); - - /* - * get width and height of how text will be renderized - */ - int (*get_text_size) (osd_object_t *osd, const char *text, - int *width, int *height); - - /* - * close osd rendering engine - * loaded fonts are unloaded - * osd objects are closed - */ - void (*close) (osd_renderer_t *this); - - /* - * clear an osd object (empty drawing area) - */ - void (*clear) (osd_object_t *osd ); - - /* - * paste a bitmap with optional palette mapping - */ - void (*draw_bitmap) (osd_object_t *osd, uint8_t *bitmap, - int x1, int y1, int width, int height, - uint8_t *palette_map); - - /* - * send the osd to be displayed (unscaled) at given pts (0=now) - * the object is not changed. there may be subsequent drawing on it. - * overlay is blended at output (screen) resolution. - */ - int (*show_unscaled) (osd_object_t *osd, int64_t vpts ); - - /* - * see xine.h for defined XINE_OSD_CAP_ values. - */ - uint32_t (*get_capabilities) (osd_object_t *osd); - - /* private stuff */ - - pthread_mutex_t osd_mutex; - video_overlay_event_t event; - osd_object_t *osds; /* instances of osd */ - osd_font_t *fonts; /* loaded fonts */ - int textpalette; /* default textpalette */ - - xine_stream_t *stream; - -}; - -/* - * initialize the osd rendering engine - */ -osd_renderer_t *_x_osd_renderer_init( xine_stream_t *stream ); - - -/* - * The size of a text palette - */ - -#define TEXT_PALETTE_SIZE 11 - -/* - * Preassigned color indices for rendering text - * (more can be added, not exceeding OVL_PALETTE_SIZE) - */ - -#define OSD_TEXT1 (0 * TEXT_PALETTE_SIZE) -#define OSD_TEXT2 (1 * TEXT_PALETTE_SIZE) -#define OSD_TEXT3 (2 * TEXT_PALETTE_SIZE) -#define OSD_TEXT4 (3 * TEXT_PALETTE_SIZE) -#define OSD_TEXT5 (4 * TEXT_PALETTE_SIZE) -#define OSD_TEXT6 (5 * TEXT_PALETTE_SIZE) -#define OSD_TEXT7 (6 * TEXT_PALETTE_SIZE) -#define OSD_TEXT8 (7 * TEXT_PALETTE_SIZE) -#define OSD_TEXT9 (8 * TEXT_PALETTE_SIZE) -#define OSD_TEXT10 (9 * TEXT_PALETTE_SIZE) - -/* - * Defined palettes for rendering osd text - * (more can be added later) - */ - -#define NUMBER_OF_TEXT_PALETTES 4 -#define TEXTPALETTE_WHITE_BLACK_TRANSPARENT 0 -#define TEXTPALETTE_WHITE_NONE_TRANSPARENT 1 -#define TEXTPALETTE_WHITE_NONE_TRANSLUCID 2 -#define TEXTPALETTE_YELLOW_BLACK_TRANSPARENT 3 - -#ifdef __OSD_C__ - -/* This text descriptions are used for config screen */ -static const char *textpalettes_str[NUMBER_OF_TEXT_PALETTES+1] = { - "white-black-transparent", - "white-none-transparent", - "white-none-translucid", - "yellow-black-transparent", - NULL}; - - -/* - Palette entries as used by osd fonts: - - 0: not used by font, always transparent - 1: font background, usually transparent, may be used to implement - translucid boxes where the font will be printed. - 2-5: transition between background and border (usually only alpha - value changes). - 6: font border. if the font is to be displayed without border this - will probably be adjusted to font background or near. - 7-9: transition between border and foreground - 10: font color (foreground) -*/ - -/* - The palettes below were made by hand, ie, i just throw - values that seemed to do the transitions i wanted. - This can surelly be improved a lot. [Miguel] -*/ - -static const clut_t textpalettes_color[NUMBER_OF_TEXT_PALETTES][TEXT_PALETTE_SIZE] = { -/* white, black border, transparent */ - { - CLUT_Y_CR_CB_INIT(0x00, 0x00, 0x00), /*0*/ - CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), /*1*/ - CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), /*2*/ - CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), /*3*/ - CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), /*4*/ - CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), /*5*/ - CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), /*6*/ - CLUT_Y_CR_CB_INIT(0x40, 0x80, 0x80), /*7*/ - CLUT_Y_CR_CB_INIT(0x80, 0x80, 0x80), /*8*/ - CLUT_Y_CR_CB_INIT(0xc0, 0x80, 0x80), /*9*/ - CLUT_Y_CR_CB_INIT(0xff, 0x80, 0x80), /*10*/ - }, - /* white, no border, transparent */ - { - CLUT_Y_CR_CB_INIT(0x00, 0x00, 0x00), /*0*/ - CLUT_Y_CR_CB_INIT(0xff, 0x80, 0x80), /*1*/ - CLUT_Y_CR_CB_INIT(0xff, 0x80, 0x80), /*2*/ - CLUT_Y_CR_CB_INIT(0xff, 0x80, 0x80), /*3*/ - CLUT_Y_CR_CB_INIT(0xff, 0x80, 0x80), /*4*/ - CLUT_Y_CR_CB_INIT(0xff, 0x80, 0x80), /*5*/ - CLUT_Y_CR_CB_INIT(0xff, 0x80, 0x80), /*6*/ - CLUT_Y_CR_CB_INIT(0xff, 0x80, 0x80), /*7*/ - CLUT_Y_CR_CB_INIT(0xff, 0x80, 0x80), /*8*/ - CLUT_Y_CR_CB_INIT(0xff, 0x80, 0x80), /*9*/ - CLUT_Y_CR_CB_INIT(0xff, 0x80, 0x80), /*10*/ - }, - /* white, no border, translucid */ - { - CLUT_Y_CR_CB_INIT(0x00, 0x00, 0x00), /*0*/ - CLUT_Y_CR_CB_INIT(0x80, 0x80, 0x80), /*1*/ - CLUT_Y_CR_CB_INIT(0x80, 0x80, 0x80), /*2*/ - CLUT_Y_CR_CB_INIT(0x80, 0x80, 0x80), /*3*/ - CLUT_Y_CR_CB_INIT(0x80, 0x80, 0x80), /*4*/ - CLUT_Y_CR_CB_INIT(0x80, 0x80, 0x80), /*5*/ - CLUT_Y_CR_CB_INIT(0x80, 0x80, 0x80), /*6*/ - CLUT_Y_CR_CB_INIT(0xa0, 0x80, 0x80), /*7*/ - CLUT_Y_CR_CB_INIT(0xc0, 0x80, 0x80), /*8*/ - CLUT_Y_CR_CB_INIT(0xe0, 0x80, 0x80), /*9*/ - CLUT_Y_CR_CB_INIT(0xff, 0x80, 0x80), /*10*/ - }, - /* yellow, black border, transparent */ - { - CLUT_Y_CR_CB_INIT(0x00, 0x00, 0x00), /*0*/ - CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), /*1*/ - CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), /*2*/ - CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), /*3*/ - CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), /*4*/ - CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), /*5*/ - CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), /*6*/ - CLUT_Y_CR_CB_INIT(0x40, 0x84, 0x60), /*7*/ - CLUT_Y_CR_CB_INIT(0x70, 0x88, 0x40), /*8*/ - CLUT_Y_CR_CB_INIT(0xb0, 0x8a, 0x20), /*9*/ - CLUT_Y_CR_CB_INIT(0xff, 0x90, 0x00), /*10*/ - }, -}; - -static const uint8_t textpalettes_trans[NUMBER_OF_TEXT_PALETTES][TEXT_PALETTE_SIZE] = { - {0, 0, 3, 6, 8, 10, 12, 14, 15, 15, 15 }, - {0, 0, 0, 0, 0, 0, 2, 6, 9, 12, 15 }, - {0, 8, 9, 10, 11, 12, 13, 14, 15, 15, 15 }, - {0, 0, 3, 6, 8, 10, 12, 14, 15, 15, 15 }, -}; - -#endif /* __OSD_C__ */ - -#endif - diff --git a/src/xine-engine/plugin_catalog.h b/src/xine-engine/plugin_catalog.h deleted file mode 100644 index 909756e2b..000000000 --- a/src/xine-engine/plugin_catalog.h +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright (C) 2000-2003 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - * - * $Id: plugin_catalog.h,v 1.21 2006/09/26 05:19:49 dgp85 Exp $ - * - * xine-internal header: Definitions for plugin lists - * - */ - -#ifndef _PLUGIN_CATALOG_H -#define _PLUGIN_CATALOG_H - -#ifdef XINE_COMPILE -# include "xine_plugin.h" -# include "xineutils.h" -#else -# include <xine/xine_plugin.h> -# include <xine/xineutils.h> -#endif - -#define DECODER_MAX 128 -#define PLUGIN_MAX 256 - -/* the engine takes this many plugins for one stream type */ -#define PLUGINS_PER_TYPE 10 - -#define CACHE_CATALOG_VERSION 3 -#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 no_unload; /* set if the file can't be unloaded */ -} plugin_file_t ; - -typedef struct { - plugin_file_t *file; - plugin_info_t *info; - void *plugin_class; - xine_list_t *config_entry_list; - int ref; /* count intances of plugins */ - int priority; -} plugin_node_t ; - -struct plugin_catalog_s { - xine_sarray_t *plugin_lists[PLUGIN_TYPE_MAX]; - - xine_sarray_t *cache_list; - xine_list_t *file_list; - - plugin_node_t *audio_decoder_map[DECODER_MAX][PLUGINS_PER_TYPE]; - plugin_node_t *video_decoder_map[DECODER_MAX][PLUGINS_PER_TYPE]; - plugin_node_t *spu_decoder_map[DECODER_MAX][PLUGINS_PER_TYPE]; - - const char *ids[PLUGIN_MAX]; - - /* memory block for the decoder priority config entry descriptions */ - char *prio_desc[DECODER_MAX]; - - pthread_mutex_t lock; - - int plugin_count; - int decoder_count; -}; -typedef struct plugin_catalog_s plugin_catalog_t; - -/* - * load plugins into catalog - * - * all input+demux plugins will be fully loaded+initialized - * decoder plugins are loaded on demand - * video/audio output plugins have special load/probe functions - */ -void _x_scan_plugins (xine_t *this) XINE_PROTECTED; - - -/* - * dispose all currently loaded plugins (shutdown) - */ - -void _x_dispose_plugins (xine_t *this) XINE_PROTECTED; - -#endif diff --git a/src/xine-engine/post.c b/src/xine-engine/post.c index 6ae96e982..651bb10f3 100644 --- a/src/xine-engine/post.c +++ b/src/xine-engine/post.c @@ -15,9 +15,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - * - * $Id: post.c,v 1.32 2006/01/27 07:46:15 tmattern Exp $ + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ /* @@ -27,7 +25,7 @@ #define POST_INTERNAL #define XINE_ENGINE_INTERNAL -#include "post.h" +#include <xine/post.h> #include <stdarg.h> @@ -59,7 +57,7 @@ static void post_video_open(xine_video_port_t *port_gen, xine_stream_t *stream) _x_post_rewire(port->post); _x_post_inc_usage(port); if (port->port_lock) pthread_mutex_lock(port->port_lock); - port->original_port->open(port->original_port, stream); + (port->original_port->open) (port->original_port, stream); if (port->port_lock) pthread_mutex_unlock(port->port_lock); port->stream = stream; } @@ -149,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; @@ -192,16 +198,18 @@ 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, &width, &height, &img_duration)) { - new_port->open(new_port, input_port->stream); + (new_port->open) (new_port, input_port->stream); input_port->original_port->close(input_port->original_port, input_port->stream); } 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; } @@ -223,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; @@ -362,6 +371,9 @@ vo_frame_t *_x_post_intercept_video_frame(vo_frame_t *frame, post_video_port_t * /* make a copy and attach the original */ xine_fast_memcpy(new_frame, frame, sizeof(vo_frame_t)); new_frame->next = frame; + + if (new_frame->stream) + _x_refcounter_inc(new_frame->stream->refcounter); /* modify the frame with the intercept functions */ new_frame->port = &port->new_port; @@ -379,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) @@ -399,6 +412,9 @@ vo_frame_t *_x_post_restore_video_frame(vo_frame_t *frame, post_video_port_t *po /* propagate any changes */ _x_post_frame_copy_down(frame, original); + if (frame->stream) + _x_refcounter_dec(frame->stream->refcounter); + /* put the now free slot into the free frames list */ pthread_mutex_lock(&port->free_frames_lock); frame->next = port->free_frame_slots; @@ -410,6 +426,11 @@ vo_frame_t *_x_post_restore_video_frame(vo_frame_t *frame, post_video_port_t *po void _x_post_frame_copy_down(vo_frame_t *from, vo_frame_t *to) { /* propagate changes downwards (from decoders to video out) */ + if (from->stream) + _x_refcounter_inc(from->stream->refcounter); + if (to->stream) + _x_refcounter_dec(to->stream->refcounter); + to->pts = from->pts; to->bad_frame = from->bad_frame; to->duration = from->duration; @@ -432,8 +453,14 @@ void _x_post_frame_copy_down(vo_frame_t *from, vo_frame_t *to) { void _x_post_frame_copy_up(vo_frame_t *to, vo_frame_t *from) { /* propagate changes upwards (from video out to decoders) */ + if (from->stream) + _x_refcounter_inc(from->stream->refcounter); + if (to->stream) + _x_refcounter_dec(to->stream->refcounter); + to->vpts = from->vpts; to->duration = from->duration; + to->stream = from->stream; if (to->extra_info != from->extra_info) _x_extra_info_merge(to->extra_info, from->extra_info); @@ -441,6 +468,11 @@ void _x_post_frame_copy_up(vo_frame_t *to, vo_frame_t *from) { void _x_post_frame_u_turn(vo_frame_t *frame, xine_stream_t *stream) { /* frame's travel will end here => do the housekeeping */ + if (stream) + _x_refcounter_inc(stream->refcounter); + if (frame->stream) + _x_refcounter_dec(frame->stream->refcounter); + frame->stream = stream; if (stream) { _x_extra_info_merge(frame->extra_info, stream->video_decoder_extra_info); @@ -583,7 +615,7 @@ static int post_audio_open(xine_audio_port_t *port_gen, xine_stream_t *stream, _x_post_rewire(port->post); _x_post_inc_usage(port); if (port->port_lock) pthread_mutex_lock(port->port_lock); - result = port->original_port->open(port->original_port, stream, bits, rate, mode); + result = (port->original_port->open) (port->original_port, stream, bits, rate, mode); if (port->port_lock) pthread_mutex_unlock(port->port_lock); port->stream = stream; port->bits = bits; @@ -680,16 +712,18 @@ 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, &bits, &rate, &mode)) { - new_port->open(new_port, input_port->stream, bits, rate, mode); + (new_port->open) (new_port, input_port->stream, bits, rate, mode); input_port->original_port->close(input_port->original_port, input_port->stream); } 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; } @@ -857,7 +891,7 @@ int _x_post_dispose(post_plugin_t *this) { /* since the plugin loader does not know, when the plugin gets disposed, * we have to handle the reference counter here */ pthread_mutex_lock(&this->xine->plugin_catalog->lock); - ((plugin_node_t *)this->node)->ref--; + this->node->ref--; pthread_mutex_unlock(&this->xine->plugin_catalog->lock); return 1; diff --git a/src/xine-engine/post.h b/src/xine-engine/post.h deleted file mode 100644 index bcdc3c54b..000000000 --- a/src/xine-engine/post.h +++ /dev/null @@ -1,393 +0,0 @@ -/* - * Copyright (C) 2000-2004 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - * - * $Id: post.h,v 1.26 2007/02/20 01:13:08 dgp85 Exp $ - * - * post plugin definitions - * - */ - -#ifndef XINE_POST_H -#define XINE_POST_H - -#ifdef XINE_COMPILE -# include "xine.h" -# include "video_out.h" -# include "audio_out.h" -# include "xine_internal.h" -# include "xineutils.h" -#else -# include <xine.h> -# include <xine/video_out.h> -# include <xine/audio_out.h> -# include <xine/xine_internal.h> -# include <xine/xineutils.h> -#endif - -#define POST_PLUGIN_IFACE_VERSION 9 - - -typedef struct post_class_s post_class_t; -typedef struct post_plugin_s post_plugin_t; -typedef struct post_in_s post_in_t; -typedef struct post_out_s post_out_t; - -struct post_class_s { - - /* - * open a new instance of this plugin class - */ - post_plugin_t* (*open_plugin) (post_class_t *this, int inputs, - xine_audio_port_t **audio_target, - xine_video_port_t **video_target); - - /* - * return short, human readable identifier for this plugin class - */ - char* (*get_identifier) (post_class_t *this); - - /* - * return human readable (verbose = 1 line) description for - * this plugin class - */ - char* (*get_description) (post_class_t *this); - - /* - * free all class-related resources - */ - - void (*dispose) (post_class_t *this); -}; - -struct post_plugin_s { - - /* public part of the plugin */ - xine_post_t xine_post; - - /* - * the connections announced by the plugin - * the plugin must fill these with xine_post_{in,out}_t on init - */ - xine_list_t *input; - xine_list_t *output; - - /* - * close down, free all resources - */ - void (*dispose) (post_plugin_t *this); - - /* has dispose been called */ - int dispose_pending; - - /* plugins don't have to init the stuff below */ - - /* - * the running ticket - * - * the plugin must assure to check for ticket revocation in - * intervals of finite length; this means that you must release - * the ticket before any operation that might block; - * note that all port functions are safe in this respect - * - * the running ticket is assigned to you by the engine - */ - xine_ticket_t *running_ticket; - - /* this is needed by the engine to decrement the reference counter - * on disposal of the plugin, but since this is useful, we expose it */ - xine_t *xine; - - /* used when the user requests a list of all inputs/outputs */ - const char **input_ids; - const char **output_ids; - - /* used by plugin loader */ - void *node; -}; - -/* helper function to initialize a post_plugin_t */ -void _x_post_init(post_plugin_t *post, int num_audio_inputs, int num_video_inputs) XINE_PROTECTED; - -struct post_in_s { - - /* public part of the input */ - xine_post_in_t xine_in; - - /* backward reference so that you have access to the post plugin */ - post_plugin_t *post; - - /* you can fill this to your liking */ - void *user_data; -}; - -struct post_out_s { - - /* public part of the output */ - xine_post_out_t xine_out; - - /* backward reference so that you have access to the post plugin */ - post_plugin_t *post; - - /* you can fill this to your liking */ - void *user_data; -}; - - -/* Post plugins work by intercepting calls to video or audio ports - * in the sense of the decorator design pattern. They reuse the - * functions of a given target port, but add own functionality in - * front of that port by creating a new port structure and filling in - * the function pointers with pointers to own functions that - * would do something and then call the original port function. - * - * Much the same is done with video frames which have their own - * set of functions attached that you might need to decorate. - */ - - -/* helper structure for intercepting video port calls */ -typedef struct post_video_port_s post_video_port_t; -struct post_video_port_s { - - /* the new public port with replaced function pointers */ - xine_video_port_t new_port; - - /* the original port to call its functions from inside yours */ - xine_video_port_t *original_port; - - /* if you want to decide yourself, whether a given frame should - * be intercepted, fill in this function; get_frame() acts as - * a template method and asks your function; return a boolean; - * the default is to intercept all frames */ - int (*intercept_frame)(post_video_port_t *self, vo_frame_t *frame); - - /* the new frame function pointers */ - vo_frame_t *new_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; - * the default is _not_ to intercept the overlay manager */ - int (*intercept_ovl)(post_video_port_t *self); - - /* the new public overlay manager with replaced function pointers */ - video_overlay_manager_t *new_manager; - - /* the original manager to call its functions from inside yours */ - video_overlay_manager_t *original_manager; - - /* 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; - - /* point to a mutex here, if you need some synchronization */ - pthread_mutex_t *port_lock; - pthread_mutex_t *frame_lock; - pthread_mutex_t *manager_lock; - - /* backward reference so that you have access to the post plugin - * when the call only gives you the port */ - post_plugin_t *post; - - /* you can fill this to your liking */ - void *user_data; - -#ifdef POST_INTERNAL - /* some of the above members are to be directly included here, but - * adding the structures would mean that post_video_port_t becomes - * depended of the sizes of these structs; solution: we add pointers - * above and have them point into the memory provided here; - * note that the overlay manager needs to be first so that we can - * reconstruct the post_video_port_t* from overlay manager calls */ - - /* any change here requires a change in _x_post_ovl_manager_to_port() - * below! */ - - video_overlay_manager_t manager_storage; - vo_frame_t frame_storage; - - /* this is used to keep a linked list of free vo_frame_t's */ - vo_frame_t *free_frame_slots; - pthread_mutex_t free_frames_lock; -#endif -}; - -/* use this to create a new decorated video port in which - * port functions will be replaced with own implementations; - * for convenience, this can also create a related post_in_t and post_out_t */ -post_video_port_t *_x_post_intercept_video_port(post_plugin_t *post, xine_video_port_t *port, - post_in_t **input, post_out_t **output) XINE_PROTECTED; - -/* use this to decorate and to undecorate a frame so that its functions - * can be replaced with own implementations, decoration is usually done in - * get_frame(), undecoration in frame->free() */ -vo_frame_t *_x_post_intercept_video_frame(vo_frame_t *frame, post_video_port_t *port) XINE_PROTECTED; -vo_frame_t *_x_post_restore_video_frame(vo_frame_t *frame, post_video_port_t *port) XINE_PROTECTED; - -/* when you want to pass a frame call on to the original issuer of the frame, - * you need to propagate potential changes up and down the pipe, so the usual - * procedure for this situation would be: - * - * _x_post_frame_copy_down(frame, frame->next); - * frame->next->function(frame->next); - * _x_post_frame_copy_up(frame, frame->next); - */ -void _x_post_frame_copy_down(vo_frame_t *from, vo_frame_t *to) XINE_PROTECTED; -void _x_post_frame_copy_up(vo_frame_t *to, vo_frame_t *from) XINE_PROTECTED; - -/* when you shortcut a frames usual draw() travel so that it will never reach - * the draw() function of the original issuer, you still have to do some - * housekeeping on the frame, before returning control up the pipe */ -void _x_post_frame_u_turn(vo_frame_t *frame, xine_stream_t *stream) XINE_PROTECTED; - -/* use this to create a new, trivially decorated overlay manager in which - * port functions can be replaced with own implementations */ -void _x_post_intercept_overlay_manager(video_overlay_manager_t *manager, post_video_port_t *port) XINE_PROTECTED; - -/* pointer retrieval functions */ -static inline post_video_port_t *_x_post_video_frame_to_port(vo_frame_t *frame) { - return (post_video_port_t *)frame->port; -} - -static inline post_video_port_t *_x_post_ovl_manager_to_port(video_overlay_manager_t *manager) { -#ifdef POST_INTERNAL - return (post_video_port_t *)( (uint8_t *)manager - - (unsigned)&(((post_video_port_t *)NULL)->manager_storage) ); -#else - return (post_video_port_t *)( (uint8_t *)manager - sizeof(post_video_port_t) ); -#endif -} - - -/* helper structure for intercepting audio port calls */ -typedef struct post_audio_port_s post_audio_port_t; -struct post_audio_port_s { - - /* the new public port with replaced function pointers */ - xine_audio_port_t new_port; - - /* 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() */ - uint32_t bits; - uint32_t rate; - uint32_t mode; - - /* point to a mutex here, if you need some synchronization */ - pthread_mutex_t *port_lock; - - /* backward reference so that you have access to the post plugin - * when the call only gives you the port */ - post_plugin_t *post; - - /* you can fill this to your liking */ - void *user_data; -}; - -/* use this to create a new decorated audio port in which - * port functions will be replaced with own implementations */ -post_audio_port_t *_x_post_intercept_audio_port(post_plugin_t *post, xine_audio_port_t *port, - post_in_t **input, post_out_t **output) XINE_PROTECTED; - - -/* this will allow pending rewire operations, calling this at the beginning - * of decoder-called functions like get_buffer() and open() is a good idea - * (if you do not intercept get_buffer() or open(), this will be done automatically) */ -static inline void _x_post_rewire(post_plugin_t *post) { - if (post->running_ticket->ticket_revoked) - post->running_ticket->renew(post->running_ticket, 1); -} - -/* with these functions you can switch interruptions like rewiring or engine pausing - * off for a block of code; use this only when really necessary */ -static inline void _x_post_lock(post_plugin_t *post) { - post->running_ticket->acquire(post->running_ticket, 1); -} -static inline void _x_post_unlock(post_plugin_t *post) { - post->running_ticket->release(post->running_ticket, 1); - _x_post_rewire(post); -} - -/* the standard disposal operation; returns 1 if the plugin is really - * disposed and you should free everything you malloc()ed yourself */ -int _x_post_dispose(post_plugin_t *post) XINE_PROTECTED; - - -/* macros to handle usage counter */ - -/* WARNING! - * note that _x_post_dec_usage() can call dispose, so be sure to - * not use any potentially already freed memory after this */ - -#define _x_post_inc_usage(port) \ -do { \ - pthread_mutex_lock(&(port)->usage_lock); \ - (port)->usage_count++; \ - pthread_mutex_unlock(&(port)->usage_lock); \ -} while(0) - -#define _x_post_dec_usage(port) \ -do { \ - pthread_mutex_lock(&(port)->usage_lock); \ - (port)->usage_count--; \ - if ((port)->usage_count == 0) { \ - if ((port)->post->dispose_pending) { \ - pthread_mutex_unlock(&(port)->usage_lock); \ - (port)->post->dispose((port)->post); \ - } else \ - pthread_mutex_unlock(&(port)->usage_lock); \ - } else \ - pthread_mutex_unlock(&(port)->usage_lock); \ -} while(0) - - -/* macros to create parameter descriptors */ - -#define START_PARAM_DESCR( param_t ) \ -static param_t temp_s; \ -static xine_post_api_parameter_t temp_p[] = { - -#define PARAM_ITEM( param_type, var, enumv, min, max, readonly, descr ) \ -{ param_type, #var, sizeof(temp_s.var), \ - (char*)&temp_s.var-(char*)&temp_s, enumv, min, max, readonly, descr }, - -#define END_PARAM_DESCR( name ) \ - { POST_PARAM_TYPE_LAST, NULL, 0, 0, NULL, 0, 0, 1, NULL } \ -}; \ -static xine_post_api_descr_t name = { \ - sizeof( temp_s ), \ - temp_p \ -}; - -#endif diff --git a/src/xine-engine/refcounter.c b/src/xine-engine/refcounter.c index 18c2ad1ce..4bb6a0351 100644 --- a/src/xine-engine/refcounter.c +++ b/src/xine-engine/refcounter.c @@ -15,10 +15,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - * - * $Id: refcounter.c,v 1.2 2006/09/26 05:19:49 dgp85 Exp $ - * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ #define LOG_MODULE "refcounter" #define LOG_VERBOSE @@ -26,8 +23,8 @@ #define LOG */ -#include "xine_internal.h" -#include "refcounter.h" +#include <xine/xine_internal.h> +#include <xine/refcounter.h> refcounter_t* _x_new_refcounter(void *object, void (*destructor)(void *)) { diff --git a/src/xine-engine/refcounter.h b/src/xine-engine/refcounter.h deleted file mode 100644 index 640366b1f..000000000 --- a/src/xine-engine/refcounter.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (C) 2000-2004 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - * - * $Id: refcounter.h,v 1.2 2006/09/26 05:19:49 dgp85 Exp $ - * - */ -#ifndef HAVE_REFCOUNTER_H -#define HAVE_REFCOUNTER_H - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <pthread.h> - -typedef struct { - pthread_mutex_t lock; - int count; - void* object; /* referenced object */ - void (*destructor)(void *); /* object destructor */ -} refcounter_t; - -typedef void (*refcounter_destructor)(void*); - -refcounter_t* _x_new_refcounter(void *object, refcounter_destructor destructor) XINE_PROTECTED; - -int _x_refcounter_inc(refcounter_t *refcounter) XINE_PROTECTED; - -int _x_refcounter_dec(refcounter_t *refcounter) XINE_PROTECTED; - -void _x_refcounter_dispose(refcounter_t *refcounter) XINE_PROTECTED; - -#endif /* HAVE_REFCOUNTER_H */ diff --git a/src/xine-engine/resample.c b/src/xine-engine/resample.c index a7b16917c..f907c965e 100644 --- a/src/xine-engine/resample.c +++ b/src/xine-engine/resample.c @@ -15,35 +15,41 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - * - * $Id: resample.c,v 1.10 2006/09/26 05:19:49 dgp85 Exp $ + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ #ifdef HAVE_CONFIG_H #include "config.h" #endif +#include <string.h> #include <inttypes.h> -#include "attributes.h" -#include "resample.h" +#include <xine/attributes.h> +#include <xine/resample.h> /* contributed by paul flinders */ -void _x_audio_out_resample_mono(int16_t* input_samples, uint32_t in_samples, +void _x_audio_out_resample_mono(int16_t *last_sample, + int16_t* input_samples, uint32_t in_samples, int16_t* output_samples, uint32_t out_samples) { unsigned int osample; /* 16+16 fixed point math */ - uint32_t isample = 0; - uint32_t istep = ((in_samples-2) << 16)/(out_samples-2); + uint32_t isample = 0xFFFF0000U; + uint32_t istep = (in_samples << 16) / out_samples + 1; #ifdef VERBOSE printf ("Audio : resample %d samples to %d\n", in_samples, out_samples); #endif - for (osample = 0; osample < out_samples - 1; osample++) { + for (osample = 0; osample < out_samples && isample >= 0xFFFF0000U; osample++) { + uint32_t t = isample&0xffff; + output_samples[osample] = (last_sample[0] * (0x10000-t) + input_samples[0] * t) >> 16; + isample += istep; + } + + for (; osample < out_samples; osample++) { int s1; int s2; int16_t os; @@ -58,23 +64,31 @@ void _x_audio_out_resample_mono(int16_t* input_samples, uint32_t in_samples, isample += istep; } - output_samples[out_samples-1] = input_samples[in_samples-1]; + last_sample[0] = input_samples[in_samples - 1]; } -void _x_audio_out_resample_stereo(int16_t* input_samples, uint32_t in_samples, +void _x_audio_out_resample_stereo(int16_t *last_sample, + int16_t* input_samples, uint32_t in_samples, int16_t* output_samples, uint32_t out_samples) { unsigned int osample; /* 16+16 fixed point math */ - uint32_t isample = 0; - uint32_t istep = ((in_samples-2) << 16)/(out_samples-2); + uint32_t isample = 0xFFFF0000U; + uint32_t istep = (in_samples << 16) / out_samples + 1; #ifdef VERBOSE printf ("Audio : resample %d samples to %d\n", in_samples, out_samples); #endif - for (osample = 0; osample < out_samples - 1; osample++) { + for (osample = 0; osample < out_samples && isample >= 0xFFFF0000U; osample++) { + uint32_t t = isample&0xffff; + output_samples[osample*2 ] = (last_sample[0] * (0x10000-t) + input_samples[0] * t) >> 16; + output_samples[osample*2+1] = (last_sample[1] * (0x10000-t) + input_samples[1] * t) >> 16; + isample += istep; + } + + for (; osample < out_samples; osample++) { int s1; int s2; int16_t os; @@ -94,25 +108,34 @@ void _x_audio_out_resample_stereo(int16_t* input_samples, uint32_t in_samples, output_samples[(osample * 2 )+1] = os; isample += istep; } - output_samples[out_samples*2-2] = input_samples[in_samples*2-2]; - output_samples[out_samples*2-1] = input_samples[in_samples*2-1]; + memcpy (last_sample, &input_samples[in_samples*2-2], 2 * sizeof (last_sample[0])); } -void _x_audio_out_resample_4channel(int16_t* input_samples, uint32_t in_samples, +void _x_audio_out_resample_4channel(int16_t *last_sample, + int16_t* input_samples, uint32_t in_samples, int16_t* output_samples, uint32_t out_samples) { unsigned int osample; /* 16+16 fixed point math */ - uint32_t isample = 0; - uint32_t istep = ((in_samples-2) << 16)/(out_samples-2); + uint32_t isample = 0xFFFF0000U; + uint32_t istep = (in_samples << 16) / out_samples + 1; #ifdef VERBOSE printf ("Audio : resample %d samples to %d\n", in_samples, out_samples); #endif - for (osample = 0; osample < out_samples - 1; osample++) { + for (osample = 0; osample < out_samples && isample >= 0xFFFF0000U; osample++) { + uint32_t t = isample&0xffff; + output_samples[osample*4 ] = (last_sample[0] * (0x10000-t) + input_samples[0] * t) >> 16; + output_samples[osample*4+1] = (last_sample[1] * (0x10000-t) + input_samples[1] * t) >> 16; + output_samples[osample*4+2] = (last_sample[2] * (0x10000-t) + input_samples[2] * t) >> 16; + output_samples[osample*4+3] = (last_sample[3] * (0x10000-t) + input_samples[3] * t) >> 16; + isample += istep; + } + + for (; osample < out_samples; osample++) { int s1; int s2; int16_t os; @@ -145,28 +168,35 @@ void _x_audio_out_resample_4channel(int16_t* input_samples, uint32_t in_samples, isample += istep; } - output_samples[out_samples*4-4] = input_samples[in_samples*4-4]; - output_samples[out_samples*4-3] = input_samples[in_samples*4-3]; - output_samples[out_samples*4-2] = input_samples[in_samples*4-2]; - output_samples[out_samples*4-1] = input_samples[in_samples*4-1]; - + memcpy (last_sample, &input_samples[in_samples*4-4], 4 * sizeof (last_sample[0])); } -void _x_audio_out_resample_5channel(int16_t* input_samples, uint32_t in_samples, +void _x_audio_out_resample_5channel(int16_t *last_sample, + int16_t* input_samples, uint32_t in_samples, int16_t* output_samples, uint32_t out_samples) { unsigned int osample; /* 16+16 fixed point math */ - uint32_t isample = 0; - uint32_t istep = ((in_samples-2) << 16)/(out_samples-2); + uint32_t isample = 0xFFFF0000U; + uint32_t istep = (in_samples << 16) / out_samples + 1; #ifdef VERBOSE printf ("Audio : resample %d samples to %d\n", in_samples, out_samples); #endif - for (osample = 0; osample < out_samples - 1; osample++) { + for (osample = 0; osample < out_samples && isample >= 0xFFFF0000U; osample++) { + uint32_t t = isample&0xffff; + output_samples[osample*5 ] = (last_sample[0] * (0x10000-t) + input_samples[0] * t) >> 16; + output_samples[osample*5+1] = (last_sample[1] * (0x10000-t) + input_samples[1] * t) >> 16; + output_samples[osample*5+2] = (last_sample[2] * (0x10000-t) + input_samples[2] * t) >> 16; + output_samples[osample*5+3] = (last_sample[3] * (0x10000-t) + input_samples[3] * t) >> 16; + output_samples[osample*5+4] = (last_sample[4] * (0x10000-t) + input_samples[4] * t) >> 16; + isample += istep; + } + + for (; osample < out_samples; osample++) { int s1; int s2; int16_t os; @@ -205,29 +235,36 @@ void _x_audio_out_resample_5channel(int16_t* input_samples, uint32_t in_samples, isample += istep; } - - output_samples[out_samples*5-5] = input_samples[in_samples*5-5]; - output_samples[out_samples*5-4] = input_samples[in_samples*5-4]; - output_samples[out_samples*5-3] = input_samples[in_samples*5-3]; - output_samples[out_samples*5-2] = input_samples[in_samples*5-2]; - output_samples[out_samples*5-1] = input_samples[in_samples*5-1]; + memcpy (last_sample, &input_samples[in_samples*5-5], 5 * sizeof (last_sample[0])); } -void _x_audio_out_resample_6channel(int16_t* input_samples, uint32_t in_samples, +void _x_audio_out_resample_6channel(int16_t *last_sample, + int16_t* input_samples, uint32_t in_samples, int16_t* output_samples, uint32_t out_samples) { unsigned int osample; /* 16+16 fixed point math */ - uint32_t isample = 0; - uint32_t istep = ((in_samples-2) << 16)/(out_samples-2); + uint32_t isample = 0xFFFF0000U; + uint32_t istep = (in_samples << 16) / out_samples + 1; #ifdef VERBOSE printf ("Audio : resample %d samples to %d\n", in_samples, out_samples); #endif - for (osample = 0; osample < out_samples - 1; osample++) { + for (osample = 0; osample < out_samples && isample >= 0xFFFF0000U; osample++) { + uint32_t t = isample&0xffff; + output_samples[osample*6 ] = (last_sample[0] * (0x10000-t) + input_samples[0] * t) >> 16; + output_samples[osample*6+1] = (last_sample[1] * (0x10000-t) + input_samples[1] * t) >> 16; + output_samples[osample*6+2] = (last_sample[2] * (0x10000-t) + input_samples[2] * t) >> 16; + output_samples[osample*6+3] = (last_sample[3] * (0x10000-t) + input_samples[3] * t) >> 16; + output_samples[osample*6+4] = (last_sample[4] * (0x10000-t) + input_samples[4] * t) >> 16; + output_samples[osample*6+5] = (last_sample[5] * (0x10000-t) + input_samples[5] * t) >> 16; + isample += istep; + } + + for (; osample < out_samples; osample++) { int s1; int s2; int16_t os; @@ -272,13 +309,7 @@ void _x_audio_out_resample_6channel(int16_t* input_samples, uint32_t in_samples, isample += istep; } - - output_samples[out_samples*6-6] = input_samples[in_samples*6-6]; - output_samples[out_samples*6-5] = input_samples[in_samples*6-5]; - output_samples[out_samples*6-4] = input_samples[in_samples*6-4]; - output_samples[out_samples*6-3] = input_samples[in_samples*6-3]; - output_samples[out_samples*6-2] = input_samples[in_samples*6-2]; - output_samples[out_samples*6-1] = input_samples[in_samples*6-1]; + memcpy (last_sample, &input_samples[in_samples*6-6], 6 * sizeof (last_sample[0])); } void _x_audio_out_resample_8to16(int8_t* input_samples, diff --git a/src/xine-engine/resample.h b/src/xine-engine/resample.h deleted file mode 100644 index e5aad1afa..000000000 --- a/src/xine-engine/resample.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (C) 2000-2003 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - * - * $Id: resample.h,v 1.6 2006/09/26 05:19:49 dgp85 Exp $ - * - * utilitiy functions for audio drivers - * - * FIXME: not all of them are implemented yet - */ - -#ifndef HAVE_RESAMPLE_H -#define HAVE_RESAMPLE_H - -void _x_audio_out_resample_stereo(int16_t* input_samples, uint32_t in_samples, - int16_t* output_samples, uint32_t out_samples) XINE_PROTECTED; - -void _x_audio_out_resample_mono(int16_t* input_samples, uint32_t in_samples, - int16_t* output_samples, uint32_t out_samples) XINE_PROTECTED; - -void _x_audio_out_resample_4channel(int16_t* input_samples, uint32_t in_samples, - int16_t* output_samples, uint32_t out_samples) XINE_PROTECTED; - -void _x_audio_out_resample_5channel(int16_t* input_samples, uint32_t in_samples, - int16_t* output_samples, uint32_t out_samples) XINE_PROTECTED; - -void _x_audio_out_resample_6channel(int16_t* input_samples, uint32_t in_samples, - int16_t* output_samples, uint32_t out_samples) XINE_PROTECTED; - -void _x_audio_out_resample_8to16(int8_t* input_samples, - int16_t* output_samples, uint32_t samples) XINE_PROTECTED; - -void _x_audio_out_resample_16to8(int16_t* input_samples, - int8_t* output_samples, uint32_t samples) XINE_PROTECTED; - -void _x_audio_out_resample_monotostereo(int16_t* input_samples, - int16_t* output_samples, uint32_t frames) XINE_PROTECTED; - -void _x_audio_out_resample_stereotomono(int16_t* input_samples, - int16_t* output_samples, uint32_t frames) XINE_PROTECTED; - -#endif diff --git a/src/xine-engine/scratch.c b/src/xine-engine/scratch.c index 67281b041..7376a3f9e 100644 --- a/src/xine-engine/scratch.c +++ b/src/xine-engine/scratch.c @@ -15,12 +15,9 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - * - * $Id: scratch.c,v 1.24 2007/01/19 00:12:22 dgp85 Exp $ + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * top-level xine functions - * */ #ifdef HAVE_CONFIG_H @@ -29,7 +26,6 @@ #include <stdio.h> #include <stdarg.h> -#include <string.h> /* For memset */ #define LOG_MODULE "scratch" #define LOG_VERBOSE @@ -37,8 +33,8 @@ #define LOG */ -#include "xineutils.h" -#include "scratch.h" +#include <xine/xineutils.h> +#include <xine/scratch.h> static void __attribute__((__format__(__printf__, 2, 0))) scratch_printf (scratch_buffer_t *this, const char *format, va_list argp) @@ -108,15 +104,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/scratch.h b/src/xine-engine/scratch.h deleted file mode 100644 index bcfe815c3..000000000 --- a/src/xine-engine/scratch.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (C) 2000-2006 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - * - * $Id: scratch.h,v 1.13 2007/01/19 00:12:22 dgp85 Exp $ - * - * scratch buffer for log output - * - */ - -#ifndef HAVE_SCRATCH_H -#define HAVE_SCRATCH_H - -#include <stdarg.h> -#include <pthread.h> - -typedef struct scratch_buffer_s scratch_buffer_t; - -#define SCRATCH_LINE_LEN_MAX 1024 - -struct scratch_buffer_s { - - void -#if __GNUC__ >= 3 - __attribute__((__format__(__printf__, 2, 0))) -#endif - (*scratch_printf) (scratch_buffer_t *this, const char *format, va_list ap); - - char **(*get_content) (scratch_buffer_t *this); - - void (*dispose) (scratch_buffer_t *this); - - char **lines; - char **ordered; - - int num_lines; - int cur; - - pthread_mutex_t lock; -}; - -scratch_buffer_t *_x_new_scratch_buffer (int num_lines) XINE_PROTECTED; - -#endif diff --git a/src/xine-engine/spu.c b/src/xine-engine/spu.c new file mode 100644 index 000000000..c610a43c9 --- /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/xine_internal.h> +#include <xine/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_decoder.h b/src/xine-engine/spu_decoder.h deleted file mode 100644 index 66ab5e54a..000000000 --- a/src/xine-engine/spu_decoder.h +++ /dev/null @@ -1,144 +0,0 @@ -/* - * spu_decoder_api.h - * - * Copyright (C) James Courtier-Dutton James@superbug.demon.co.uk - July 2001 - * - * This file is part of xine, a unix 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 GNU Make; see the file COPYING. If not, write to - * the Free Software Foundation, - * - */ - -#ifndef HAVE_SPU_API_H -#define HAVE_SPU_API_H - -#ifdef XINE_COMPILE -# include <inttypes.h> -# include "buffer.h" -#else -# include <xine/os_types.h> -# include <xine/buffer.h> -#endif - -#define SPU_DECODER_IFACE_VERSION 16 - -/* - * generic xine spu decoder plugin interface - */ - -typedef struct spu_decoder_class_s spu_decoder_class_t; -typedef struct spu_decoder_s spu_decoder_t; - -struct spu_decoder_class_s { - - /* - * open a new instance of this plugin class - */ - spu_decoder_t* (*open_plugin) (spu_decoder_class_t *this, xine_stream_t *stream); - - /* - * return short, human readable identifier for this plugin class - */ - char* (*get_identifier) (spu_decoder_class_t *this); - - /* - * return human readable (verbose = 1 line) description for - * this plugin class - */ - char* (*get_description) (spu_decoder_class_t *this); - - /* - * free all class-related resources - */ - void (*dispose) (spu_decoder_class_t *this); -}; - - -struct spu_decoder_s { - - /* - * decode data from buf and feed the overlay to overlay manager - */ - void (*decode_data) (spu_decoder_t *this, buf_element_t *buf); - - /* - * reset decoder after engine flush (prepare for new - * SPU data not related to recently decoded data) - */ - void (*reset) (spu_decoder_t *this); - - /* - * inform decoder that a time reference discontinuity has happened. - * that is, it must forget any currently held pts value - */ - void (*discontinuity) (spu_decoder_t *this); - - /* - * close down, free all resources - */ - void (*dispose) (spu_decoder_t *this); - - /* - * When the SPU decoder also handles data used in user interaction, - * you can query the related information here. The typical example - * for this is DVD NAV packets which are handled by the SPU decoder - * and can be received readily parsed from here. - * The caller and the decoder must agree on the structure which is - * passed here. - * This function pointer may be NULL, if the plugin does not have - * such functionality. - */ - int (*get_interact_info) (spu_decoder_t *this, void *data); - - /* - * When the SPU decoder also handles menu overlays for user inter- - * action, you can set a menu button here. The typical example for - * this is DVD menus. - * This function pointer may be NULL, if the plugin does not have - * such functionality. - */ - void (*set_button) (spu_decoder_t *this_gen, int32_t button, int32_t mode); - - void *node; /* used by plugin loader */ -}; - - -/* SPU decoders differ from video and audio decoders in one significant - * way: unlike audio and video, SPU streams are not continuous; - * this results in another difference, programmers have to consider: - * while both audio and video decoders are automatically blocked in - * their get_buffer()/get_frame() methods when the output cannot take - * any more data, this does not work for SPU, because it could take - * minutes before the next free slot becomes available and we must not - * block the decoder thread for that long; - * therefore, we provide a convenience function for SPU decoders which - * implements a wait until a timestamp sufficiently close to the VPTS - * of the next SPU is reached, but the waiting will end before that, - * if some outside condition requires us to release the decoder thread - * to other tasks; - * if this functions returns with 1, noone needs the decoder thread and - * you may continue waiting; if it returns 0, finish whatever you are - * doing and return; - * the usual pattern for SPU decoders is this: - * - * do { - * spu = prepare_spu(); - * int thread_vacant = _x_spu_decoder_sleep(this->stream, spu->vpts); - * int success = process_spu(spu); - * } while (!success && thread_vacant); - */ -int _x_spu_decoder_sleep(xine_stream_t *, int64_t next_spu_vpts) XINE_PROTECTED; - -#endif /* HAVE_SPUDEC_H */ diff --git a/src/xine-engine/tvmode.c b/src/xine-engine/tvmode.c deleted file mode 100644 index b7a34e673..000000000 --- a/src/xine-engine/tvmode.c +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (C) 2000-2003 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - * - * $Id: tvmode.c,v 1.17 2003/12/09 00:02:37 f1rmb Exp $ - * - * tvmode - TV output selection - * - * Currently uses nvtvd (Dirk Thierbach <dthierbach@gmx.de>) - * for setting TV mode - * xine support hacked in by Matthias Hopf <mat@mshopf.de> - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <unistd.h> - -#include "xine_internal.h" -#include "xineutils.h" - -/* nvtv support is deprecated (and will be removed) - * these dummy functions are only here to prevent serious breakage - * until front ends are updated. - */ - -int xine_tvmode_switch (xine_t *this, int type, int width, int height, double fps) { - /* not supported: return regular mode */ - return 0; -} - -void xine_tvmode_size (xine_t *this, int *width, int *height, - double *pixelratio, double *fps) { -} - -int xine_tvmode_init (xine_t *this) { - return 0; -} - -void xine_tvmode_exit (xine_t *this) { -} - -void xine_tvmode_set_tvsystem(xine_t *self, xine_tvsystem system) { -} - -int xine_tvmode_use(xine_t *self, int use_tvmode) { - return 0; -} diff --git a/src/xine-engine/video_decoder.c b/src/xine-engine/video_decoder.c index fee75ec76..ca6e7aa23 100644 --- a/src/xine-engine/video_decoder.c +++ b/src/xine-engine/video_decoder.c @@ -15,10 +15,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - * - * $Id: video_decoder.c,v 1.163 2007/02/20 00:34:58 dgp85 Exp $ - * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ #ifdef HAVE_CONFIG_H @@ -28,6 +25,7 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <unistd.h> #define XINE_ENGINE_INTERNAL @@ -37,8 +35,8 @@ #define LOG */ -#include "xine_internal.h" -#include "xineutils.h" +#include <xine/xine_internal.h> +#include <xine/xineutils.h> #include <sched.h> #define SPU_SLEEP_INTERVAL (90000/2) @@ -110,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_decoder.h b/src/xine-engine/video_decoder.h deleted file mode 100644 index 42120b724..000000000 --- a/src/xine-engine/video_decoder.h +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright (C) 2000-2004 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - * - * $Id: video_decoder.h,v 1.14 2004/09/26 22:54:52 valtri Exp $ - * - * xine video decoder plugin interface - * - */ - -#ifndef HAVE_VIDEO_DECODER_H -#define HAVE_VIDEO_DECODER_H - -#ifdef XINE_COMPILE -# include <inttypes.h> -# include "buffer.h" -#else -# include <xine/os_types.h> -# include <xine/buffer.h> -#endif - -#define VIDEO_DECODER_IFACE_VERSION 18 - - -/* - * generic xine video decoder plugin interface - */ - -typedef struct video_decoder_class_s video_decoder_class_t; -typedef struct video_decoder_s video_decoder_t; - -struct video_decoder_class_s { - - /* - * open a new instance of this plugin class - */ - video_decoder_t* (*open_plugin) (video_decoder_class_t *this, xine_stream_t *stream); - - /* - * return short, human readable identifier for this plugin class - */ - char* (*get_identifier) (video_decoder_class_t *this); - - /* - * return human readable (verbose = 1 line) description for - * this plugin class - */ - char* (*get_description) (video_decoder_class_t *this); - - /* - * free all class-related resources - */ - void (*dispose) (video_decoder_class_t *this); -}; - - -struct video_decoder_s { - - /* - * decode data from buf and feed decoded frames to - * video output - */ - void (*decode_data) (video_decoder_t *this, buf_element_t *buf); - - /* - * reset decoder after engine flush (prepare for new - * video data not related to recently decoded data) - */ - void (*reset) (video_decoder_t *this); - - /* - * inform decoder that a time reference discontinuity has happened. - * that is, it must forget any currently held pts value - */ - void (*discontinuity) (video_decoder_t *this); - - /* - * flush out any frames that are still stored in the decoder - */ - void (*flush) (video_decoder_t *this); - - /* - * close down, free all resources - */ - void (*dispose) (video_decoder_t *this); - - - void *node; /*used by plugin loader */ - -}; - -#endif diff --git a/src/xine-engine/video_out.c b/src/xine-engine/video_out.c index 2a3ee1980..0bab612ce 100644 --- a/src/xine-engine/video_out.c +++ b/src/xine-engine/video_out.c @@ -15,9 +15,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - * - * $Id: video_out.c,v 1.228 2007/04/01 01:03:06 dgp85 Exp $ + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * frame allocation / queuing / scheduling / output functions */ @@ -46,10 +44,10 @@ #define LOG */ -#include "xine_internal.h" -#include "video_out.h" -#include "metronom.h" -#include "xineutils.h" +#include <xine/xine_internal.h> +#include <xine/video_out.h> +#include <xine/metronom.h> +#include <xine/xineutils.h> #define NUM_FRAME_BUFFERS 15 #define MAX_USEC_TO_SLEEP 20000 @@ -71,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; @@ -128,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; @@ -144,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); @@ -173,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); } @@ -213,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); @@ -467,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); @@ -952,6 +979,7 @@ static vo_frame_t *get_next_frame (vos_t *this, int64_t cur_vpts, if (!img->stream || _x_stream_info_get(img->stream, XINE_STREAM_INFO_VIDEO_HAS_STILL) || + !img->stream->video_fifo || img->stream->video_fifo->size(img->stream->video_fifo) < 10) { lprintf ("possible still frame\n"); @@ -1043,6 +1071,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. @@ -1088,7 +1142,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 ); } @@ -1218,7 +1272,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; @@ -1601,6 +1658,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); } @@ -1670,6 +1730,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. */ @@ -1765,6 +1834,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; @@ -1784,8 +1854,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, @@ -1806,6 +1874,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)); @@ -1842,6 +1928,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 deleted file mode 100644 index 7b42c43ed..000000000 --- a/src/xine-engine/video_out.h +++ /dev/null @@ -1,455 +0,0 @@ -/* - * Copyright (C) 2000-2004 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - * - * $Id: video_out.h,v 1.114 2006/09/26 05:19:49 dgp85 Exp $ - * - * - * xine version of video_out.h - * - * vo_frame : frame containing yuv data and timing info, - * transferred between video_decoder and video_output - * - * vo_driver : lowlevel, platform-specific video output code - * - * vo_port : generic frame_handling code, uses - * a vo_driver for output - * - */ - -#ifndef HAVE_VIDEO_OUT_H -#define HAVE_VIDEO_OUT_H - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <pthread.h> - -#ifdef XINE_COMPILE -# include "xine.h" -# include "buffer.h" -#else -# include <xine.h> -# include <xine/buffer.h> -#endif - - -typedef struct vo_frame_s vo_frame_t; -typedef struct vo_driver_s vo_driver_t; -typedef struct video_driver_class_s video_driver_class_t; -typedef struct vo_overlay_s vo_overlay_t; -typedef struct video_overlay_manager_s video_overlay_manager_t; - -/* public part, video drivers may add private fields - * - * Remember that adding new functions to this structure requires - * adaption of the post plugin decoration layer. Be sure to look into - * src/xine-engine/post.[ch]. - */ -struct vo_frame_s { - /* - * member functions - */ - - /* Duplicate picture data and acceleration specific data of a frame. */ - /* if the image format isn't already known by Xine. Currently this is needed */ - /* For all image formats except XINE_IMGFMT_YV12 and XINE_IMGFMT_YUY2 */ - void (*proc_duplicate_frame_data) (vo_frame_t *vo_img, vo_frame_t *src); - - /* tell video driver to copy/convert the whole of this frame, may be NULL */ - /* at least one of proc_frame() and proc_slice() MUST set the variable proc_called to 1 */ - void (*proc_frame) (vo_frame_t *vo_img); - - /* tell video driver to copy/convert a slice of this frame, may be NULL */ - /* at least one of proc_frame() and proc_slice() MUST set the variable proc_called to 1 */ - void (*proc_slice) (vo_frame_t *vo_img, uint8_t **src); - - /* tell video driver that the decoder starts a new field */ - void (*field) (vo_frame_t *vo_img, int which_field); - - /* append this frame to the display queue, - returns number of frames to skip if decoder is late */ - /* when the frame does not originate from a stream, it is legal to pass an anonymous stream */ - int (*draw) (vo_frame_t *vo_img, xine_stream_t *stream); - - /* lock frame as reference, must be paired with free. - * most decoders/drivers do not need to call this function since - * newly allocated frames are already locked once. - */ - void (*lock) (vo_frame_t *vo_img); - - /* this frame is no longer used by the decoder, video driver, etc */ - void (*free) (vo_frame_t *vo_img); - - /* free memory/resources for this frame */ - void (*dispose) (vo_frame_t *vo_img); - - /* - * public variables to decoders and vo drivers - * changing anything here will require recompiling them both - */ - int64_t pts; /* presentation time stamp (1/90000 sec) */ - int64_t vpts; /* virtual pts, generated by metronom */ - int bad_frame; /* e.g. frame skipped or based on skipped frame */ - int duration; /* frame length in time, in 1/90000 sec */ - - /* yv12 (planar) base[0]: y, base[1]: u, base[2]: v */ - /* yuy2 (interleaved) base[0]: yuyv..., base[1]: --, base[2]: -- */ - uint8_t *base[3]; - int pitches[3]; - - /* info that can be used for interlaced output (e.g. tv-out) */ - int top_field_first; - int repeat_first_field; - /* note: progressive_frame is set wrong on many mpeg2 streams. for - * that reason, this flag should be interpreted as a "hint". - */ - int progressive_frame; - int picture_coding_type; - - /* cropping to be done */ - int crop_left, crop_right, crop_top, crop_bottom; - - /* extra info coming from input or demuxers */ - extra_info_t *extra_info; - - /* additional information to be able to duplicate frames: */ - int width, height; - double ratio; /* aspect ratio */ - int format; /* IMGFMT_YV12 or IMGFMT_YUY2 */ - - int drawn; /* used by decoder, frame has already been drawn */ - int flags; /* remember the frame flags */ - int proc_called; /* track use of proc_*() methods */ - - /* Used to carry private data for accelerated plugins.*/ - void *accel_data; - - /* "backward" references to where this frame originates from */ - xine_video_port_t *port; - vo_driver_t *driver; - xine_stream_t *stream; - - /* displacement for overlays */ - int overlay_offset_x, overlay_offset_y; - - /* - * that part is used only by video_out.c for frame management - * 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; -}; - - -/* - * Remember that adding new functions to this structure requires - * adaption of the post plugin decoration layer. Be sure to look into - * src/xine-engine/post.[ch]. - */ -struct xine_video_port_s { - - uint32_t (*get_capabilities) (xine_video_port_t *self); /* for constants see below */ - - /* open display driver for video output */ - /* when you are not a full-blown stream, but still need to open the port - * (e.g. you are a post plugin) it is legal to pass an anonymous stream */ - void (*open) (xine_video_port_t *self, xine_stream_t *stream); - - /* - * get_frame - allocate an image buffer from display driver - * - * params : width == width of video to display. - * height == height of video to display. - * ratio == aspect ration information - * format == FOURCC descriptor of image format - * flags == field/prediction flags - */ - vo_frame_t* (*get_frame) (xine_video_port_t *self, uint32_t width, - uint32_t height, double ratio, - int format, int flags); - - /* retrieves the last displayed frame (useful for taking snapshots) */ - vo_frame_t* (*get_last_frame) (xine_video_port_t *self); - - /* overlay stuff */ - void (*enable_ovl) (xine_video_port_t *self, int ovl_enable); - - /* get overlay manager */ - video_overlay_manager_t* (*get_overlay_manager) (xine_video_port_t *self); - - /* flush video_out fifo */ - void (*flush) (xine_video_port_t *self); - - /* Get/Set video property - * - * See VO_PROP_* bellow - */ - int (*get_property) (xine_video_port_t *self, int property); - int (*set_property) (xine_video_port_t *self, int property, int value); - - /* return true if port is opened for this stream, stream can be anonymous */ - int (*status) (xine_video_port_t *self, xine_stream_t *stream, - int *width, int *height, int64_t *img_duration); - - /* video driver is no longer used by decoder => close */ - /* when you are not a full-blown stream, but still need to close the port - * (e.g. you are a post plugin) it is legal to pass an anonymous stream */ - void (*close) (xine_video_port_t *self, xine_stream_t *stream); - - /* called on xine exit */ - void (*exit) (xine_video_port_t *self); - - /* the driver in use */ - vo_driver_t *driver; - -}; - -/* constants for the get/set property functions */ -#define VO_PROP_INTERLACED 0 -#define VO_PROP_ASPECT_RATIO 1 -#define VO_PROP_HUE 2 -#define VO_PROP_SATURATION 3 -#define VO_PROP_CONTRAST 4 -#define VO_PROP_BRIGHTNESS 5 -#define VO_PROP_COLORKEY 6 -#define VO_PROP_AUTOPAINT_COLORKEY 7 -#define VO_PROP_ZOOM_X 8 -#define VO_PROP_PAN_SCAN 9 -#define VO_PROP_TVMODE 10 -#define VO_PROP_MAX_NUM_FRAMES 11 -#define VO_PROP_ZOOM_Y 13 -#define VO_PROP_DISCARD_FRAMES 14 /* not used by drivers */ -#define VO_PROP_WINDOW_WIDTH 15 /* read-only */ -#define VO_PROP_WINDOW_HEIGHT 16 /* read-only */ -#define VO_PROP_BUFS_IN_FIFO 17 /* read-only */ -#define VO_PROP_NUM_STREAMS 18 /* read-only */ -#define VO_NUM_PROPERTIES 19 - -/* 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. */ -#define OVL_PALETTE_SIZE 256 - -/* number of recent frames to keep in memory - these frames are needed by some deinterlace algorithms - FIXME: we need a method to flush the recent frames (new stream) -*/ -#define VO_NUM_RECENT_FRAMES 2 - -/* get_frame flags */ -#define VO_TOP_FIELD 1 -#define VO_BOTTOM_FIELD 2 -#define VO_BOTH_FIELDS (VO_TOP_FIELD | VO_BOTTOM_FIELD) -#define VO_PAN_SCAN_FLAG 4 -#define VO_INTERLACED_FLAG 8 -#define VO_NEW_SEQUENCE_FLAG 16 /* set after MPEG2 Sequence Header Code (used by XvMC) */ - -/* video driver capabilities */ -#define VO_CAP_YV12 0x00000001 /* driver can handle YUV 4:2:0 pictures */ -#define VO_CAP_YUY2 0x00000002 /* driver can handle YUY2 pictures */ -#define VO_CAP_XVMC_MOCOMP 0x00000004 /* driver can use XvMC motion compensation */ -#define VO_CAP_XVMC_IDCT 0x00000008 /* driver can use XvMC idct acceleration */ -#define VO_CAP_UNSCALED_OVERLAY 0x00000010 /* driver can blend overlay at output resolution */ -#define VO_CAP_CROP 0x00000020 /* driver can crop */ -#define VO_CAP_XXMC 0x00000040 /* driver can use extended XvMC */ - - -/* - * vo_driver_s contains the functions every display driver - * has to implement. The vo_new_port function (see below) - * should then be used to construct a vo_port using this - * driver. Some of the function pointers will be copied - * directly into xine_video_port_s, others will be called - * from generic vo functions. - */ - -#define VIDEO_OUT_DRIVER_IFACE_VERSION 21 - -struct vo_driver_s { - - uint32_t (*get_capabilities) (vo_driver_t *self); /* for constants see above */ - - /* - * allocate an vo_frame_t struct, - * the driver must supply the copy, field and dispose functions - */ - vo_frame_t* (*alloc_frame) (vo_driver_t *self); - - /* - * check if the given image fullfills the format specified - * (re-)allocate memory if necessary - */ - void (*update_frame_format) (vo_driver_t *self, vo_frame_t *img, - uint32_t width, uint32_t height, - double ratio, int format, int flags); - - /* display a given frame */ - void (*display_frame) (vo_driver_t *self, vo_frame_t *vo_img); - - /* overlay_begin and overlay_end are used by drivers suporting - * persistent overlays. they can be optimized to update only when - * overlay image has changed. - * - * sequence of operation (pseudo-code): - * overlay_begin(this,img,true_if_something_changed_since_last_blend ); - * while(visible_overlays) - * overlay_blend(this,img,overlay[i]); - * overlay_end(this,img); - * - * any function pointer from this group may be set to NULL. - */ - void (*overlay_begin) (vo_driver_t *self, vo_frame_t *vo_img, int changed); - void (*overlay_blend) (vo_driver_t *self, vo_frame_t *vo_img, vo_overlay_t *overlay); - void (*overlay_end) (vo_driver_t *self, vo_frame_t *vo_img); - - /* - * these can be used by the gui directly: - */ - int (*get_property) (vo_driver_t *self, int property); - int (*set_property) (vo_driver_t *self, - int property, int value); - void (*get_property_min_max) (vo_driver_t *self, - int property, int *min, int *max); - - /* - * general purpose communication channel between gui and driver - * - * this should be used to propagate events, display data, window sizes - * etc. to the driver - */ - int (*gui_data_exchange) (vo_driver_t *self, int data_type, - void *data); - - /* check if a redraw is needed (due to resize) - * this is only used for still frames, normal video playback - * must call that inside display_frame() function. - */ - int (*redraw_needed) (vo_driver_t *self); - - /* - * free all resources, close driver - */ - void (*dispose) (vo_driver_t *self); - - void *node; /* needed by plugin_loader */ -}; - -struct video_driver_class_s { - - /* - * open a new instance of this plugin class - */ - vo_driver_t* (*open_plugin) (video_driver_class_t *self, const void *visual); - - /* - * return short, human readable identifier for this plugin class - */ - char* (*get_identifier) (video_driver_class_t *self); - - /* - * return human readable (verbose = 1 line) description for - * this plugin class - */ - char* (*get_description) (video_driver_class_t *self); - - /* - * free all class-related resources - */ - void (*dispose) (video_driver_class_t *self); -}; - - -typedef struct rle_elem_s { - uint16_t len; - uint16_t color; -} rle_elem_t; - -struct vo_overlay_s { - - rle_elem_t *rle; /* rle code buffer */ - int data_size; /* useful for deciding realloc */ - int num_rle; /* number of active rle codes */ - int x; /* x start of subpicture area */ - int y; /* y start of subpicture area */ - int width; /* width of subpicture area */ - int height; /* height of subpicture area */ - - uint32_t color[OVL_PALETTE_SIZE]; /* color lookup table */ - uint8_t trans[OVL_PALETTE_SIZE]; /* mixer key table */ - int rgb_clut; /* true if clut was converted to rgb */ - - /* define a highlight area with different colors */ - int hili_top; - int hili_bottom; - int hili_left; - int hili_right; - uint32_t hili_color[OVL_PALETTE_SIZE]; - uint8_t hili_trans[OVL_PALETTE_SIZE]; - int hili_rgb_clut; /* true if clut was converted to rgb */ - - int unscaled; /* true if it should be blended unscaled */ -}; - - -/* API to video_overlay manager - * - * Remember that adding new functions to this structure requires - * adaption of the post plugin decoration layer. Be sure to look into - * src/xine-engine/post.[ch]. - */ -struct video_overlay_manager_s { - void (*init) (video_overlay_manager_t *this_gen); - - void (*dispose) (video_overlay_manager_t *this_gen); - - int32_t (*get_handle) (video_overlay_manager_t *this_gen, int object_type ); - - void (*free_handle) (video_overlay_manager_t *this_gen, int32_t handle); - - int32_t (*add_event) (video_overlay_manager_t *this_gen, void *event); - - void (*flush_events) (video_overlay_manager_t *this_gen ); - - int (*redraw_needed) (video_overlay_manager_t *this_gen, int64_t vpts ); - - void (*multiple_overlay_blend) (video_overlay_manager_t *this_gen, int64_t vpts, - vo_driver_t *output, vo_frame_t *vo_img, int enabled); -}; - -/* - * build a video_out_port from - * a given video driver - */ -xine_video_port_t *_x_vo_new_port (xine_t *xine, vo_driver_t *driver, int grabonly) XINE_PROTECTED; - -#ifdef __cplusplus -} -#endif - -#endif - diff --git a/src/xine-engine/video_overlay.c b/src/xine-engine/video_overlay.c index 04a3034a3..44080c469 100644 --- a/src/xine-engine/video_overlay.c +++ b/src/xine-engine/video_overlay.c @@ -15,10 +15,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - * - * $Id: video_overlay.c,v 1.41 2006/09/26 00:28:14 dgp85 Exp $ - * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ #include <stdlib.h> @@ -28,11 +25,11 @@ #include <sys/stat.h> #include <fcntl.h> -#include "buffer.h" -#include "xine_internal.h" +#include <xine/buffer.h> +#include <xine/xine_internal.h> #include "bswap.h" -#include "xineutils.h" -#include "video_overlay.h" +#include <xine/xineutils.h> +#include <xine/video_overlay.h> /* #define LOG_DEBUG @@ -49,10 +46,10 @@ typedef struct video_overlay_showing_s { typedef struct video_overlay_s { - xine_t *xine; - video_overlay_manager_t video_overlay; + xine_t *xine; + pthread_mutex_t events_mutex; video_overlay_events_t events[MAX_EVENTS]; pthread_mutex_t objects_mutex; @@ -288,10 +285,18 @@ static int32_t video_overlay_add_event(video_overlay_manager_t *this_gen, void } if( event->object.overlay ) { + int i; + for(i = 0; i < OVL_PALETTE_SIZE; i++) { + if(event->object.overlay->trans[i] >= OVL_MAX_OPACITY) + event->object.overlay->trans[i] = OVL_MAX_OPACITY; + if(event->object.overlay->hili_trans[i] >= OVL_MAX_OPACITY) + event->object.overlay->hili_trans[i] = OVL_MAX_OPACITY; + } + this->events[new_event].event->object.overlay = xine_xmalloc (sizeof(vo_overlay_t)); xine_fast_memcpy(this->events[new_event].event->object.overlay, event->object.overlay, sizeof(vo_overlay_t)); - + /* We took the callers rle and data, therefore it will be our job to free it */ /* clear callers overlay so it will not be freed twice */ memset(event->object.overlay,0,sizeof(vo_overlay_t)); @@ -387,6 +392,8 @@ static int video_overlay_event( video_overlay_t *this, int64_t vpts ) { #endif /* free any overlay associated with this event */ if (this->events[this_event].event->object.overlay != NULL) { + if( this->events[this_event].event->object.overlay->rle != NULL ) + free( this->events[this_event].event->object.overlay->rle ); free(this->events[this_event].event->object.overlay); this->events[this_event].event->object.overlay = NULL; } @@ -398,9 +405,11 @@ static int video_overlay_event( video_overlay_t *this, int64_t vpts ) { printf ("video_overlay: FREE SPU NOW\n"); #endif /* free any overlay associated with this event */ - if (this->events[this_event].event->object.overlay != NULL) { + if( this->events[this_event].event->object.overlay != NULL) { + if( this->events[this_event].event->object.overlay->rle != NULL ) + free( this->events[this_event].event->object.overlay->rle ); free(this->events[this_event].event->object.overlay); - this->events[this_event].event->object.overlay = NULL; + this->events[this_event].event->object.overlay = NULL; } /* this avoid removing this_event from the queue * (it will be removed at the end of this loop) */ diff --git a/src/xine-engine/video_overlay.h b/src/xine-engine/video_overlay.h deleted file mode 100644 index 1e7a2bcca..000000000 --- a/src/xine-engine/video_overlay.h +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright (C) 2000-2003 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - * - * $Id: video_overlay.h,v 1.21 2006/09/26 05:19:49 dgp85 Exp $ - * - */ - -#ifndef HAVE_VIDEO_OVERLAY_H -#define HAVE_VIDEO_OVERLAY_H - -#ifdef XINE_COMPILE -# include "xine_internal.h" -#else -# include <xine/xine_internal.h> -#endif - -#ifdef __GNUC__ -#define CLUT_Y_CR_CB_INIT(_y,_cr,_cb) {y: (_y), cr: (_cr), cb: (_cb)} -#else -#define CLUT_Y_CR_CB_INIT(_y,_cr,_cb) { (_cb), (_cr), (_y) } -#endif - -#define MAX_OBJECTS 50 -#define MAX_EVENTS 50 -#define MAX_SHOWING 16 - -#define OVERLAY_EVENT_NULL 0 -#define OVERLAY_EVENT_SHOW 1 -#define OVERLAY_EVENT_HIDE 2 -#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 */ -} 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. - */ - video_overlay_object_t object; /* The image data. */ -} video_overlay_event_t; - -video_overlay_manager_t *_x_video_overlay_new_manager(xine_t *) XINE_PROTECTED; - -#endif diff --git a/src/xine-engine/vo_scale.c b/src/xine-engine/vo_scale.c index b2f3001d0..567b3984a 100644 --- a/src/xine-engine/vo_scale.c +++ b/src/xine-engine/vo_scale.c @@ -15,10 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * - * $Id: vo_scale.c,v 1.39 2006/09/26 08:00:02 dgp85 Exp $ - * * Contains common code to calculate video scaling parameters. * In short, it will map frame dimensions to screen/window size. * Takes into account aspect ratio correction and zooming. @@ -34,8 +32,8 @@ #define LOG */ -#include "xine_internal.h" -#include "vo_scale.h" +#include <xine/xine_internal.h> +#include <xine/vo_scale.h> /* * convert delivered height/width to ideal width/height @@ -313,28 +311,21 @@ void _x_vo_scale_translate_gui2video(vo_scale_t *this, *vid_y = y; } -/* - * Returns description of a given ratio code +/*/ + * @brief Table for description of a given ratio code. + * + * @note changing the size of the elements of the array will break + * ABI, so please don't do that unless you absolutely can't continue + * with the current size. */ - -char *_x_vo_scale_aspect_ratio_name(int a) { - - switch (a) { - case XINE_VO_ASPECT_AUTO: - return "auto"; - case XINE_VO_ASPECT_SQUARE: - return "square"; - case XINE_VO_ASPECT_4_3: - return "4:3"; - case XINE_VO_ASPECT_ANAMORPHIC: - return "16:9"; - case XINE_VO_ASPECT_DVB: - return "2:1"; - default: - return "unknown"; - } -} - +const char _x_vo_scale_aspect_ratio_name_table[][8] = { + "auto", /* XINE_VO_ASPECT_AUTO */ + "square", /* XINE_VO_ASPECT_SQUARE */ + "4:3", /* XINE_VO_ASPECT_4_3 */ + "16:9", /* XINE_VO_ASPECT_ANAMORPHIC */ + "2:1", /* XINE_VO_ASPECT_DVB */ + "unknown" /* All the rest */ +}; /* * config callbacks diff --git a/src/xine-engine/vo_scale.h b/src/xine-engine/vo_scale.h deleted file mode 100644 index 917b6c99e..000000000 --- a/src/xine-engine/vo_scale.h +++ /dev/null @@ -1,206 +0,0 @@ -/* - * Copyright (C) 2000-2003 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - * - * $Id: vo_scale.h,v 1.14 2006/09/26 05:19:49 dgp85 Exp $ - * - * vo_scale.h - * - * keeps video scaling information - */ - -#ifndef HAVE_VO_SCALE_H -#define HAVE_VO_SCALE_H - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#ifdef XINE_COMPILE -# include "configfile.h" -#else -# include <xine/configfile.h> -#endif - -typedef struct { - int x, y; - int w, h; -} vo_scale_rect_t; - -struct vo_scale_s { - - /* true if driver supports frame zooming */ - int support_zoom; - - /* forces direct mapping between frame pixels and screen pixels */ - int scaling_disabled; - - /* size / aspect ratio calculations */ - - /* - * "delivered" size: - * frame dimension / aspect as delivered by the decoder - * used (among other things) to detect frame size changes - * units: frame pixels - */ - int delivered_width; - int delivered_height; - double delivered_ratio; - - /* - * required cropping: - * units: frame pixels - */ - int crop_left; - int crop_right; - int crop_top; - int crop_bottom; - - /* - * displayed part of delivered images, - * taking zoom into account - * units: frame pixels - */ - int displayed_xoffset; - int displayed_yoffset; - int displayed_width; - int displayed_height; - double zoom_factor_x, zoom_factor_y; - - /* - * user's aspect selection - */ - int user_ratio; - - /* - * "gui" size / offset: - * what gui told us about where to display the video - * units: screen pixels - */ - int gui_x, gui_y; - int gui_width, gui_height; - int gui_win_x, gui_win_y; - - /* - * video + display pixel aspect - * One pixel of height 1 has this width - * This may be corrected by the driver in order to fit the video seamlessly - */ - double gui_pixel_aspect; - double video_pixel_aspect; - - /* - * "output" size: - * - * this is finally the ideal size "fitted" into the - * gui size while maintaining the aspect ratio - * units: screen pixels - */ - int output_width; - int output_height; - int output_xoffset; - int output_yoffset; - - - /* */ - int force_redraw; - - - /* gui callbacks */ - - void *user_data; - void (*frame_output_cb) (void *user_data, - int video_width, int video_height, - double video_pixel_aspect, - int *dest_x, int *dest_y, - int *dest_width, int *dest_height, - double *dest_pixel_aspect, - int *win_x, int *win_y); - - void (*dest_size_cb) (void *user_data, - int video_width, int video_height, - double video_pixel_aspect, - int *dest_width, int *dest_height, - double *dest_pixel_aspect); - - /* borders */ - vo_scale_rect_t border[4]; - - /* - * border ratios to determine image position in the - * viewport; these are set by user config - */ - double output_horizontal_position; - double output_vertical_position; - -}; - -typedef struct vo_scale_s vo_scale_t; - - -/* - * convert delivered height/width to ideal width/height - * taking into account aspect ratio and zoom factor - */ - -void _x_vo_scale_compute_ideal_size (vo_scale_t *self) XINE_PROTECTED; - - -/* - * make ideal width/height "fit" into the gui - */ - -void _x_vo_scale_compute_output_size (vo_scale_t *self) XINE_PROTECTED; - -/* - * return true if a redraw is needed due resizing, zooming, - * aspect ratio changing, etc. - */ - -int _x_vo_scale_redraw_needed (vo_scale_t *self) XINE_PROTECTED; - -/* - * - */ - -void _x_vo_scale_translate_gui2video(vo_scale_t *self, - int x, int y, - int *vid_x, int *vid_y) XINE_PROTECTED; - -/* - * Returns description of a given ratio code - */ - -char *_x_vo_scale_aspect_ratio_name(int a) XINE_PROTECTED; - -/* - * initialize rescaling struct - */ - -void _x_vo_scale_init(vo_scale_t *self, int support_zoom, - int scaling_disabled, config_values_t *config ) XINE_PROTECTED; - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/xine-engine/xine.c b/src/xine-engine/xine.c index 32c2d7672..c6dc8a2ce 100644 --- a/src/xine-engine/xine.c +++ b/src/xine-engine/xine.c @@ -15,9 +15,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - * - * $Id: xine.c,v 1.342 2007/02/20 00:37:02 dgp85 Exp $ + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ /* @@ -37,7 +35,8 @@ #include <pthread.h> #include <stdarg.h> #include <stdio.h> -#if defined (__linux__) +#include <ctype.h> +#if defined (__linux__) || defined (__GLIBC__) #include <endian.h> #elif defined (__FreeBSD__) #include <machine/endian.h> @@ -47,6 +46,8 @@ #include <locale.h> #endif +#include <basedir.h> + #define LOG_MODULE "xine" #define LOG_VERBOSE /* @@ -58,26 +59,29 @@ #define XINE_ENGINE_INTERNAL #define METRONOM_CLOCK_INTERNAL -#include "xine_internal.h" -#include "plugin_catalog.h" -#include "audio_out.h" -#include "video_out.h" -#include "demuxers/demux.h" -#include "buffer.h" -#include "spu_decoder.h" -#include "input/input_plugin.h" -#include "metronom.h" -#include "configfile.h" -#include "osd.h" - -#include "xineutils.h" -#include "compat.h" +#include <xine/xine_internal.h> +#include <xine/plugin_catalog.h> +#include <xine/audio_out.h> +#include <xine/video_out.h> +#include <xine/demux.h> +#include <xine/buffer.h> +#include <xine/spu_decoder.h> +#include <xine/input_plugin.h> +#include <xine/metronom.h> +#include <xine/configfile.h> +#include <xine/osd.h> +#include <xine/spu.h> + +#include <xine/xineutils.h> +#include <xine/compat.h> #ifdef WIN32 # include <fcntl.h> # include <winsock.h> #endif /* WIN32 */ +#include "load_plugins.h" + static void mutex_cleanup (void *mutex) { pthread_mutex_unlock ((pthread_mutex_t *) mutex); @@ -128,25 +132,97 @@ void _x_extra_info_merge( extra_info_t *dst, extra_info_t *src ) { } } -static void ticket_acquire(xine_ticket_t *this, int irrevocable) { +static int acquire_allowed_to_block(xine_ticket_t *this) { + pthread_t own_id = pthread_self(); + unsigned entry; + unsigned new_size; + + for(entry = 0; entry < this->holder_thread_count; ++entry) { + if(this->holder_threads[entry].holder == own_id) { + /* This thread may already hold this ticket */ + this->holder_threads[entry].count++; + return (this->holder_threads[entry].count == 1); + } + } + /* If we get this far, this thread hasn't claimed this ticket before. + We need to give it a new entry in the list, then return true */ + for(entry = 0; entry < this->holder_thread_count; ++entry) { + if(this->holder_threads[entry].count == 0) { + this->holder_threads[entry].holder = own_id; + this->holder_threads[entry].count = 1; + return 1; + } + } + /* List too small. Realloc to larger size */ + new_size = this->holder_thread_count * 2; + lprintf("Reallocing from %d to %d entries\n", this->holder_thread_count, new_size); + + this->holder_threads = realloc(this->holder_threads, sizeof(*this->holder_threads) * new_size); + memset(this->holder_threads + this->holder_thread_count, 0, this->holder_thread_count); + + /* Old size is equivalent to index of first newly allocated entry*/ + this->holder_threads[this->holder_thread_count].count = 1; + this->holder_threads[this->holder_thread_count].holder = own_id; + this->holder_thread_count = new_size; + + return 1; +} + +static int ticket_acquire_internal(xine_ticket_t *this, int irrevocable, int nonblocking) { + int must_wait = 0; pthread_mutex_lock(&this->lock); + int allowed_to_block = acquire_allowed_to_block(this); if (this->ticket_revoked && !this->irrevocable_tickets) - pthread_cond_wait(&this->issued, &this->lock); + must_wait = !nonblocking; else if (this->atomic_revoke && !pthread_equal(this->atomic_revoker_thread, pthread_self())) + must_wait = 1; + + if (must_wait && allowed_to_block) { + if (nonblocking) { + pthread_mutex_unlock(&this->lock); + return 0; + } + pthread_cond_wait(&this->issued, &this->lock); + } this->tickets_granted++; if (irrevocable) this->irrevocable_tickets++; pthread_mutex_unlock(&this->lock); + return 1; } -static void ticket_release(xine_ticket_t *this, int irrevocable) { +static int ticket_acquire_nonblocking(xine_ticket_t *this, int irrevocable) { + return ticket_acquire_internal(this, irrevocable, 1); +} + +static void ticket_acquire(xine_ticket_t *this, int irrevocable) { + ticket_acquire_internal(this, irrevocable, 0); +} + +static int release_allowed_to_block(xine_ticket_t *this) { + pthread_t own_id = pthread_self(); + unsigned entry; + + for(entry = 0; entry < this->holder_thread_count; ++entry) { + if(this->holder_threads[entry].holder == own_id) { + this->holder_threads[entry].count--; + return this->holder_threads[entry].count == 0; + } + } + lprintf("BUG! Ticket 0x%p released by a thread that never took it! Allowing code to continue\n", this); + _x_assert(0); + return 1; +} + +static void ticket_release_internal(xine_ticket_t *this, int irrevocable, int nonblocking) { pthread_mutex_lock(&this->lock); + int allowed_to_block = release_allowed_to_block(this); this->tickets_granted--; if (irrevocable) @@ -154,12 +230,22 @@ static void ticket_release(xine_ticket_t *this, int irrevocable) { if (this->ticket_revoked && !this->tickets_granted) pthread_cond_broadcast(&this->revoked); - if (this->ticket_revoked && !this->irrevocable_tickets) - pthread_cond_wait(&this->issued, &this->lock); + if (allowed_to_block) { + if (this->ticket_revoked && !this->irrevocable_tickets && !nonblocking) + pthread_cond_wait(&this->issued, &this->lock); + } pthread_mutex_unlock(&this->lock); } +static void ticket_release_nonblocking(xine_ticket_t *this, int irrevocable) { + ticket_release_internal(this, irrevocable, 1); +} + +static void ticket_release(xine_ticket_t *this, int irrevocable) { + ticket_release_internal(this, irrevocable, 0); +} + static void ticket_renew(xine_ticket_t *this, int irrevocable) { pthread_mutex_lock(&this->lock); @@ -213,8 +299,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); @@ -228,15 +343,22 @@ static xine_ticket_t *ticket_init(void) { port_ticket = (xine_ticket_t *) xine_xmalloc(sizeof(xine_ticket_t)); - port_ticket->acquire = ticket_acquire; - port_ticket->release = ticket_release; - port_ticket->renew = ticket_renew; - port_ticket->issue = ticket_issue; - port_ticket->revoke = ticket_revoke; - port_ticket->dispose = ticket_dispose; + port_ticket->acquire_nonblocking = ticket_acquire_nonblocking; + port_ticket->acquire = ticket_acquire; + port_ticket->release_nonblocking = ticket_release_nonblocking; + port_ticket->release = ticket_release; + 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); @@ -430,16 +552,18 @@ 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)) { /* register our stream at the new output port */ - new_port->open(new_port, stream, bits, rate, mode); + (new_port->open) (new_port, stream, bits, rate, mode); stream->audio_out->close(stream->audio_out, stream); } 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; } @@ -454,21 +578,23 @@ 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)) { /* register our stream at the new output port */ - new_port->open(new_port, stream); + (new_port->open) (new_port, stream); stream->video_out->close(stream->video_out, stream); } 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; } -void xine_dispose_internal (xine_stream_t *stream); +static void xine_dispose_internal (xine_stream_t *stream); xine_stream_t *xine_stream_new (xine_t *this, xine_audio_port_t *ao, xine_video_port_t *vo) { @@ -607,9 +733,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; /* @@ -648,7 +775,7 @@ xine_stream_t *xine_stream_new (xine_t *this, return stream; } -static void mrl_unescape(char *mrl) { +void _x_mrl_unescape(char *mrl) { int i, len = strlen(mrl); for (i = 0; i < len; i++) { @@ -696,9 +823,22 @@ void _x_flush_events_queues (xine_stream_t *stream) { pthread_mutex_unlock (&stream->event_queues_lock); } +static inline int _x_path_looks_like_mrl (const char *path) +{ + if ((*path & 0xDF) < 'A' || (*path & 0xDF) > 'Z') + return 0; + + for (++path; *path; ++path) + if ((*path != '-' && *path < '0') || (*path > '9' && *path < 'A') || + (*path > 'Z' && *path < 'a') || *path > 'z') + break; + + return path[0] == ':' && path[1] == '/'; +} + static int open_internal (xine_stream_t *stream, const char *mrl) { - const char *stream_setup; + const char *stream_setup = NULL; int no_cache = 0; if (!mrl) { @@ -723,13 +863,19 @@ static int open_internal (xine_stream_t *stream, const char *mrl) { * look for a stream_setup in MRL and try finding an input plugin */ - stream_setup = mrl; - /* look for the next '#' or try the whole MRL, if none is found */ - while (*stream_setup && - (stream_setup = (strchr(stream_setup, '#') ? strchr(stream_setup, '#') : strlen(mrl) + mrl))) { - char *input_source = (char *)malloc(stream_setup - mrl + 1); - memcpy(input_source, mrl, stream_setup - mrl); - input_source[stream_setup - mrl] = '\0'; + if (isalpha (*mrl)) + { + stream_setup = mrl + 1; + while (isalnum (*stream_setup) || *stream_setup == '+' || *stream_setup == '-' || *stream_setup == '.') + ++stream_setup; + if (stream_setup[0] == ':' && stream_setup[1] == '/') + stream_setup = strchr (mrl, '#'); + else + stream_setup = NULL; + } + + { + char *input_source = strndup (mrl, stream_setup ? stream_setup - mrl : strlen (mrl)); /* * find an input plugin @@ -739,16 +885,16 @@ static int open_internal (xine_stream_t *stream, const char *mrl) { int res; xine_log (stream->xine, XINE_LOG_MSG, _("xine: found input plugin : %s\n"), - stream->input_plugin->input_class->get_description(stream->input_plugin->input_class)); + dgettext(stream->input_plugin->input_class->textdomain ? : XINE_TEXTDOMAIN, + stream->input_plugin->input_class->description)); if (stream->input_plugin->input_class->eject_media) stream->eject_class = stream->input_plugin->input_class; _x_meta_info_set_utf8(stream, XINE_META_INFO_INPUT_PLUGIN, - (stream->input_plugin->input_class->get_identifier (stream->input_plugin->input_class))); + stream->input_plugin->input_class->identifier); - res = stream->input_plugin->open(stream->input_plugin); + res = (stream->input_plugin->open) (stream->input_plugin); switch(res) { case 1: /* Open successfull */ - free(input_source); break; case -1: /* Open unsuccessfull, but correct plugin */ free(input_source); @@ -761,14 +907,9 @@ static int open_internal (xine_stream_t *stream, const char *mrl) { stream->input_plugin = NULL; stream->err = XINE_ERROR_INPUT_FAILED; } - if ( res ) break; } free(input_source); - /* if we fail when passing up to the first '#' to the input plugins, - * maybe the user stated a (invalid) MRL, with a '#' belonging to the - * input source -> look for the next '#' and try again */ - if (*stream_setup) stream_setup++; } if (!stream->input_plugin) { @@ -778,7 +919,7 @@ static int open_internal (xine_stream_t *stream, const char *mrl) { return 0; } - if (*stream_setup) { + if (stream_setup) { while (stream_setup && *stream_setup && *(++stream_setup)) { if (strncasecmp(stream_setup, "demux", 5) == 0) { @@ -796,7 +937,7 @@ static int open_internal (xine_stream_t *stream, const char *mrl) { memcpy(demux_name, tmp, strlen(tmp)); demux_name[strlen(tmp)] = '\0'; } - mrl_unescape(demux_name); + _x_mrl_unescape(demux_name); if (!(stream->demux_plugin = _x_find_demux_plugin_by_name(stream, demux_name, stream->input_plugin))) { xine_log(stream->xine, XINE_LOG_MSG, _("xine: specified demuxer %s failed to start\n"), demux_name); stream->err = XINE_ERROR_NO_DEMUX_PLUGIN; @@ -806,7 +947,7 @@ static int open_internal (xine_stream_t *stream, const char *mrl) { } _x_meta_info_set_utf8(stream, XINE_META_INFO_SYSTEMLAYER, - (stream->demux_plugin->demux_class->get_identifier(stream->demux_plugin->demux_class))); + stream->demux_plugin->demux_class->identifier); free(demux_name); } else { xprintf(stream->xine, XINE_VERBOSITY_LOG, _("xine: error while parsing mrl\n")); @@ -833,6 +974,7 @@ static int open_internal (xine_stream_t *stream, const char *mrl) { memcpy(filename, tmp, strlen(tmp)); filename[strlen(tmp)] = '\0'; } + _x_mrl_unescape(filename); xine_log(stream->xine, XINE_LOG_MSG, _("xine: join rip input plugin\n")); input_saver = _x_rip_plugin_get_instance (stream, filename); @@ -870,7 +1012,7 @@ static int open_internal (xine_stream_t *stream, const char *mrl) { memcpy(demux_name, tmp, strlen(tmp)); demux_name[strlen(tmp)] = '\0'; } - mrl_unescape(demux_name); + _x_mrl_unescape(demux_name); if (!(stream->demux_plugin = _x_find_demux_plugin_last_probe(stream, demux_name, stream->input_plugin))) { xine_log(stream->xine, XINE_LOG_MSG, _("xine: last_probed demuxer %s failed to start\n"), demux_name); stream->err = XINE_ERROR_NO_DEMUX_PLUGIN; @@ -881,7 +1023,7 @@ static int open_internal (xine_stream_t *stream, const char *mrl) { lprintf ("demux and input plugin found\n"); _x_meta_info_set_utf8(stream, XINE_META_INFO_SYSTEMLAYER, - (stream->demux_plugin->demux_class->get_identifier(stream->demux_plugin->demux_class))); + stream->demux_plugin->demux_class->identifier); free(demux_name); } else { xprintf(stream->xine, XINE_VERBOSITY_LOG, _("xine: error while parsing mrl\n")); @@ -957,7 +1099,7 @@ static int open_internal (xine_stream_t *stream, const char *mrl) { memcpy(volume, tmp, strlen(tmp)); volume[strlen(tmp)] = '\0'; } - mrl_unescape(volume); + _x_mrl_unescape(volume); xine_set_param(stream, XINE_PARAM_AUDIO_VOLUME, atoi(volume)); free(volume); } else { @@ -982,7 +1124,7 @@ static int open_internal (xine_stream_t *stream, const char *mrl) { memcpy(compression, tmp, strlen(tmp)); compression[strlen(tmp)] = '\0'; } - mrl_unescape(compression); + _x_mrl_unescape(compression); xine_set_param(stream, XINE_PARAM_AUDIO_COMPR_LEVEL, atoi(compression)); free(compression); } else { @@ -1007,7 +1149,9 @@ static int open_internal (xine_stream_t *stream, const char *mrl) { memcpy(subtitle_mrl, tmp, strlen(tmp)); subtitle_mrl[strlen(tmp)] = '\0'; } - mrl_unescape(subtitle_mrl); + /* unescape for xine_open() if the MRL looks like a raw pathname */ + if (!_x_path_looks_like_mrl(subtitle_mrl)) + _x_mrl_unescape(subtitle_mrl); stream->slave = xine_stream_new (stream->xine, NULL, stream->video_out ); stream->slave_affection = XINE_MASTER_SLAVE_PLAY | XINE_MASTER_SLAVE_STOP; if( xine_open( stream->slave, subtitle_mrl ) ) { @@ -1042,7 +1186,7 @@ static int open_internal (xine_stream_t *stream, const char *mrl) { memcpy(config_entry, tmp, strlen(tmp)); config_entry[strlen(tmp)] = '\0'; } - mrl_unescape(config_entry); + _x_mrl_unescape(config_entry); retval = _x_config_change_opt(stream->xine->config, config_entry); if (retval <= 0) { if (retval == 0) { @@ -1087,11 +1231,12 @@ static int open_internal (xine_stream_t *stream, const char *mrl) { lprintf ("demux and input plugin found\n"); _x_meta_info_set_utf8(stream, XINE_META_INFO_SYSTEMLAYER, - (stream->demux_plugin->demux_class->get_identifier(stream->demux_plugin->demux_class))); + stream->demux_plugin->demux_class->identifier); } xine_log (stream->xine, XINE_LOG_MSG, _("xine: found demuxer plugin: %s\n"), - stream->demux_plugin->demux_class->get_description(stream->demux_plugin->demux_class)); + dgettext(stream->demux_plugin->demux_class->textdomain ? : XINE_TEXTDOMAIN, + stream->demux_plugin->demux_class->description)); _x_extra_info_reset( stream->current_extra_info ); _x_extra_info_reset( stream->video_decoder_extra_info ); @@ -1110,7 +1255,11 @@ static int open_internal (xine_stream_t *stream, const char *mrl) { stream->demux_plugin->send_headers (stream->demux_plugin); if (stream->demux_plugin->get_status(stream->demux_plugin) != DEMUX_OK) { - xine_log (stream->xine, XINE_LOG_MSG, _("xine: demuxer failed to start\n")); + if (stream->demux_plugin->get_status(stream->demux_plugin) == DEMUX_FINISHED) { + xine_log (stream->xine, XINE_LOG_MSG, _("xine: demuxer is already done. that was fast!\n")); + } else { + xine_log (stream->xine, XINE_LOG_MSG, _("xine: demuxer failed to start\n")); + } _x_free_demux_plugin(stream, stream->demux_plugin); stream->demux_plugin = NULL; @@ -1315,7 +1464,7 @@ int xine_eject (xine_stream_t *stream) { return status; } -void xine_dispose_internal (xine_stream_t *stream) { +static void xine_dispose_internal (xine_stream_t *stream) { xine_list_iterator_t *ite; @@ -1411,6 +1560,8 @@ void xine_exit (xine_t *this) { WSACleanup(); #endif + xdgFreeHandle(this->basedir_handle); + free (this); } @@ -1509,9 +1660,8 @@ static void config_demux_strategy_cb (void *this_gen, xine_cfg_entry_t *entry) { static void config_save_cb (void *this_gen, xine_cfg_entry_t *entry) { xine_t *this = (xine_t *)this_gen; - char *homedir_trail_slash; + char homedir_trail_slash[strlen(xine_get_homedir()) + 2]; - homedir_trail_slash = (char *)malloc(strlen(xine_get_homedir()) + 2); sprintf(homedir_trail_slash, "%s/", xine_get_homedir()); if (entry->str_value[0] && (entry->str_value[0] != '/' || strstr(entry->str_value, "/.") || @@ -1531,13 +1681,15 @@ static void config_save_cb (void *this_gen, xine_cfg_entry_t *entry) { pthread_mutex_unlock(&this->streams_lock); } - free(homedir_trail_slash); this->save_path = entry->str_value; } 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(); @@ -1970,6 +2122,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] ) @@ -2041,3 +2196,111 @@ int xine_stream_master_slave(xine_stream_t *master, xine_stream_t *slave, slave->master = master->master; return 1; } + +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) +{ + int ticket_acquired = -1; + + if (num_video_buffers) + *num_video_buffers = (stream->video_fifo ? stream->video_fifo->size(stream->video_fifo) : 0); + + if (num_audio_buffers) + *num_audio_buffers = (stream->audio_fifo ? stream->audio_fifo->size(stream->audio_fifo) : 0); + + if ((num_video_frames && stream->video_out) + || (num_audio_frames && stream->audio_out)) { + + ticket_acquired = stream->xine->port_ticket->acquire_nonblocking(stream->xine->port_ticket, 1); + } + + if (num_video_frames) + *num_video_frames = ((ticket_acquired && stream->video_out) ? stream->video_out->get_property(stream->video_out, VO_PROP_BUFS_IN_FIFO) : 0); + + if (num_audio_frames) + *num_audio_frames = ((ticket_acquired && stream->audio_out) ? stream->audio_out->get_property(stream->audio_out, AO_PROP_BUFS_IN_FIFO) : 0); + + if (ticket_acquired > 0) + stream->xine->port_ticket->release_nonblocking(stream->xine->port_ticket, 1); + + 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_interface.c b/src/xine-engine/xine_interface.c index 166d7a3ef..c731a936f 100644 --- a/src/xine-engine/xine_interface.c +++ b/src/xine-engine/xine_interface.c @@ -15,13 +15,10 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - * - * $Id: xine_interface.c,v 1.104 2007/03/26 11:48:01 dgp85 Exp $ + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * convenience/abstraction layer, functions to implement * libxine's public interface - * */ #ifdef HAVE_CONFIG_H @@ -35,7 +32,7 @@ #include <stdlib.h> #include <pthread.h> #include <stdarg.h> -#if defined (__linux__) +#if defined (__linux__) || defined (__GLIBC__) #include <endian.h> #elif defined (__FreeBSD__) #include <machine/endian.h> @@ -43,11 +40,11 @@ #define XINE_ENGINE_INTERNAL -#include "xine_internal.h" -#include "audio_out.h" -#include "video_out.h" -#include "demuxers/demux.h" -#include "post.h" +#include <xine/xine_internal.h> +#include <xine/audio_out.h> +#include <xine/video_out.h> +#include <xine/demux.h> +#include <xine/post.h> /* * version information / checking @@ -325,15 +322,6 @@ void xine_config_reset (xine_t *this) { pthread_mutex_unlock(&config->config_lock); } -#ifndef XINE_DISABLE_DEPRECATED_FEATURES -int xine_gui_send_vo_data (xine_stream_t *stream, - int type, void *data) { - - return stream->video_driver->gui_data_exchange (stream->video_driver, - type, data); -} -#endif - int xine_port_send_gui_data (xine_video_port_t *vo, int type, void *data) { @@ -947,13 +935,13 @@ xine_post_out_t * xine_get_audio_source(xine_stream_t *stream) { int _x_message(xine_stream_t *stream, int type, ...) { xine_ui_message_data_t *data; xine_event_t event; - char *explanation; + const char *explanation; int size; int n; va_list ap; char *s, *params; char *args[1025]; - static const char *std_explanation[] = { + static const char *const std_explanation[] = { "", N_("Warning:"), N_("Unknown host:"), diff --git a/src/xine-engine/xine_internal.h b/src/xine-engine/xine_internal.h deleted file mode 100644 index 30899a4b3..000000000 --- a/src/xine-engine/xine_internal.h +++ /dev/null @@ -1,512 +0,0 @@ -/* - * Copyright (C) 2000-2005 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - * - * $Id: xine_internal.h,v 1.181 2007/01/18 23:28:46 dgp85 Exp $ - * - */ - -#ifndef HAVE_XINE_INTERNAL_H -#define HAVE_XINE_INTERNAL_H - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * include public part of xine header - */ - -#ifdef XINE_COMPILE -# include "xine.h" -# include "refcounter.h" -# include "input/input_plugin.h" -# include "demuxers/demux.h" -# include "video_out.h" -# include "audio_out.h" -# include "metronom.h" -# include "osd.h" -# include "xineintl.h" -# include "plugin_catalog.h" -# include "video_decoder.h" -# include "audio_decoder.h" -# include "spu_decoder.h" -# include "scratch.h" -# include "broadcaster.h" -# include "io_helper.h" -# include "info_helper.h" -# include "alphablend.h" -#else -# include <xine.h> -# include <xine/refcounter.h> -# include <xine/input_plugin.h> -# include <xine/demux.h> -# include <xine/video_out.h> -# include <xine/audio_out.h> -# include <xine/metronom.h> -# include <xine/osd.h> -# include <xine/xineintl.h> -# include <xine/plugin_catalog.h> -# include <xine/video_decoder.h> -# include <xine/audio_decoder.h> -# include <xine/spu_decoder.h> -# include <xine/scratch.h> -# include <xine/broadcaster.h> -# include <xine/io_helper.h> -# include <xine/info_helper.h> -# include <xine/alphablend.h> -#endif - - -#define XINE_MAX_EVENT_LISTENERS 50 -#define XINE_MAX_EVENT_TYPES 100 - -/* used by plugin loader */ -#define XINE_VERSION_CODE XINE_MAJOR_VERSION*10000+XINE_MINOR_VERSION*100+XINE_SUB_VERSION - - -/* - * log constants - */ - -#define XINE_LOG_MSG 0 /* warnings, errors, ... */ -#define XINE_LOG_PLUGIN 1 -#define XINE_LOG_TRACE 2 -#define XINE_LOG_NUM 3 /* # of log buffers defined */ - -#define XINE_STREAM_INFO_MAX 99 - -typedef struct xine_ticket_s xine_ticket_t; - -/* - * the "big" xine struct, holding everything together - */ - -struct xine_s { - - config_values_t *config; - - plugin_catalog_t *plugin_catalog; - - 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; - -#ifdef XINE_ENGINE_INTERNAL - xine_ticket_t *port_ticket; - pthread_mutex_t log_lock; -#endif -}; - -/* - * xine thread tickets - */ - -struct xine_ticket_s { - - /* the ticket owner must assure to check for ticket revocation in - * intervals of finite length; this means that you must release - * the ticket before any operation that might block - * - * you must never write to this member directly - */ - int ticket_revoked; - - /* apply for a ticket; between acquire and relese of an irrevocable - * ticket (be sure to pair them properly!), it is guaranteed that you - * will never be blocked by ticket revocation */ - void (*acquire)(xine_ticket_t *self, int irrevocable); - - /* give a ticket back */ - void (*release)(xine_ticket_t *self, int irrevocable); - - /* renew a ticket, when it has been revoked, see ticket_revoked above; - * irrevocable must be set to one, if your thread might have acquired - * irrevocable tickets you don't know of; set it to zero only when - * you know that this is impossible */ - void (*renew)(xine_ticket_t *self, int irrevocable); - -#ifdef XINE_ENGINE_INTERNAL - /* allow handing out new tickets */ - void (*issue)(xine_ticket_t *self, int atomic); - - /* revoke all tickets and deny new ones; - * a pair of atomic revoke and issue cannot be interrupted by another - * revocation or by other threads acquiring tickets */ - void (*revoke)(xine_ticket_t *self, int atomic); - - void (*dispose)(xine_ticket_t *self); - - pthread_mutex_t lock; - pthread_mutex_t revoke_lock; - pthread_cond_t issued; - pthread_cond_t revoked; - int tickets_granted; - int irrevocable_tickets; - int pending_revocations; - int atomic_revoke; - pthread_t atomic_revoker_thread; -#endif -}; - -/* - * xine event queue - */ - -struct xine_event_queue_s { - xine_list_t *events; - pthread_mutex_t lock; - pthread_cond_t new_event; - pthread_cond_t events_processed; - xine_stream_t *stream; - pthread_t *listener_thread; - xine_event_listener_cb_t callback; - int callback_running; - void *user_data; -}; - -/* - * xine_stream - per-stream parts of the xine engine - */ - -struct xine_stream_s { - - /* reference to xine context */ - xine_t *xine; - - /* metronom instance used by current stream */ - metronom_t *metronom; - - /* 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; - - /* demuxers send data to video decoders using this fifo */ - fifo_buffer_t *video_fifo; - - /* used by audio decoders */ - xine_audio_port_t *audio_out; - - /* demuxers send data to audio decoders using this fifo */ - fifo_buffer_t *audio_fifo; - - /* provide access to osd api */ - osd_renderer_t *osd_renderer; - - /* master/slave streams */ - xine_stream_t *master; /* usually a pointer to itself */ - xine_stream_t *slave; - - /* input_dvd uses this one. is it possible to add helper functions instead? */ - spu_decoder_t *spu_decoder_plugin; - - /* dxr3 use this one, should be possible to fix to use the port instead */ - vo_driver_t *video_driver; - - /* these definitely should be made private! */ - int audio_channel_auto; - int spu_decoder_streamtype; - int spu_channel_user; - int spu_channel_auto; - int spu_channel_letterbox; - int spu_channel; - -#ifdef XINE_ENGINE_INTERNAL - /* these are private variables, plugins must not access them */ - - int status; - - /* lock controlling speed change access */ - pthread_mutex_t speed_change_lock; - int ignore_speed_change; /* speed changes during stop can be disastrous */ - - 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_channel; - - 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) - >=0 => respect the user's choice - */ - int audio_channel_user; -/* int audio_channel_auto; */ - -/* spu_decoder_t *spu_decoder_plugin; */ -/* int spu_decoder_streamtype; */ - uint32_t spu_track_map[50]; - int spu_track_map_entries; -/* int spu_channel_user; */ -/* int spu_channel_auto; */ -/* int spu_channel_letterbox; */ - int spu_channel_pan_scan; -/* int spu_channel; */ - - /* lock for public xine player functions */ - pthread_mutex_t frontend_lock; - - /* stream meta information */ - /* NEVER access directly, use helpers (see info_helper.c) */ - pthread_mutex_t info_mutex; - int stream_info_public[XINE_STREAM_INFO_MAX]; - int stream_info[XINE_STREAM_INFO_MAX]; - pthread_mutex_t meta_mutex; - char *meta_info_public[XINE_STREAM_INFO_MAX]; - 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; - - /* wait for headers sent / stream decoding finished */ - pthread_mutex_t counter_lock; - pthread_cond_t counter_changed; - int header_count_audio; - int header_count_video; - int finished_count_audio; - int finished_count_video; - - /* event mechanism */ - xine_list_t *event_queues; - pthread_mutex_t event_queues_lock; - - /* 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 slave_affection; /* what operations need to be propagated down to the slave? */ - - int err; - - 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 -}; - -/* when explicitly noted, some functions accept an anonymous stream, - * which is a valid stream that does not want to be addressed. */ -#define XINE_ANON_STREAM ((xine_stream_t *)-1) - - -/* - * private function prototypes: - */ - -void _x_handle_stream_end (xine_stream_t *stream, int non_user) XINE_PROTECTED; - -/* report message to UI. usually these are async errors */ - -int _x_message(xine_stream_t *stream, int type, ...) XINE_SENTINEL XINE_PROTECTED; - -/* flush the message queues */ - -void _x_flush_events_queues (xine_stream_t *stream) XINE_PROTECTED; - - -/* find and instantiate input and demux plugins */ - -input_plugin_t *_x_find_input_plugin (xine_stream_t *stream, const char *mrl) XINE_PROTECTED; -demux_plugin_t *_x_find_demux_plugin (xine_stream_t *stream, input_plugin_t *input) XINE_PROTECTED; -demux_plugin_t *_x_find_demux_plugin_by_name (xine_stream_t *stream, const char *name, input_plugin_t *input) XINE_PROTECTED; -demux_plugin_t *_x_find_demux_plugin_last_probe(xine_stream_t *stream, const char *last_demux_name, input_plugin_t *input) XINE_PROTECTED; -input_plugin_t *_x_rip_plugin_get_instance (xine_stream_t *stream, const char *filename) XINE_PROTECTED; -input_plugin_t *_x_cache_plugin_get_instance (xine_stream_t *stream, int readahead_size) XINE_PROTECTED; -void _x_free_input_plugin (xine_stream_t *stream, input_plugin_t *input) XINE_PROTECTED; -void _x_free_demux_plugin (xine_stream_t *stream, demux_plugin_t *demux) XINE_PROTECTED; - -/* create decoder fifos and threads */ - -int _x_video_decoder_init (xine_stream_t *stream) XINE_PROTECTED; -void _x_video_decoder_shutdown (xine_stream_t *stream) XINE_PROTECTED; - -int _x_audio_decoder_init (xine_stream_t *stream) XINE_PROTECTED; -void _x_audio_decoder_shutdown (xine_stream_t *stream) XINE_PROTECTED; - -/* extra_info operations */ -void _x_extra_info_reset( extra_info_t *extra_info ) XINE_PROTECTED; - -void _x_extra_info_merge( extra_info_t *dst, extra_info_t *src ) XINE_PROTECTED; - -void _x_get_current_info (xine_stream_t *stream, extra_info_t *extra_info, int size) XINE_PROTECTED; - - -/* demuxer helper functions from demux.c */ - -/* - * Flush audio and video buffers. It is called from demuxers on - * seek/stop, and may be useful when user input changes a stream and - * xine-lib has cached buffers that have yet to be played. - * - * warning: after clearing decoders fifos an absolute discontinuity - * indication must be sent. relative discontinuities are likely - * to cause "jumps" on metronom. - */ -void _x_demux_flush_engine (xine_stream_t *stream) XINE_PROTECTED; - -void _x_demux_control_nop (xine_stream_t *stream, uint32_t flags) XINE_PROTECTED; -void _x_demux_control_newpts (xine_stream_t *stream, int64_t pts, uint32_t flags) XINE_PROTECTED; -void _x_demux_control_headers_done (xine_stream_t *stream) XINE_PROTECTED; -void _x_demux_control_start (xine_stream_t *stream) XINE_PROTECTED; -void _x_demux_control_end (xine_stream_t *stream, uint32_t flags) XINE_PROTECTED; -int _x_demux_start_thread (xine_stream_t *stream) XINE_PROTECTED; -int _x_demux_stop_thread (xine_stream_t *stream) XINE_PROTECTED; -int _x_demux_read_header (input_plugin_t *input, unsigned char *buffer, off_t size) XINE_PROTECTED; -int _x_demux_check_extension (const char *mrl, const char *extensions) XINE_PROTECTED; - -off_t _x_read_abort (xine_stream_t *stream, int fd, char *buf, off_t todo) XINE_PROTECTED; - -int _x_action_pending (xine_stream_t *stream) XINE_PROTECTED; - -void _x_demux_send_data(fifo_buffer_t *fifo, uint8_t *data, int size, - int64_t pts, uint32_t type, uint32_t decoder_flags, - int input_normpos, int input_time, int total_time, - uint32_t frame_number) XINE_PROTECTED; - -int _x_demux_read_send_data(fifo_buffer_t *fifo, input_plugin_t *input, - int size, int64_t pts, uint32_t type, - uint32_t decoder_flags, off_t input_normpos, - int input_time, int total_time, - uint32_t frame_number) XINE_PROTECTED; - -void _x_demux_send_mrl_reference (xine_stream_t *stream, int alternative, - const char *mrl, const char *title, - int start_time, int duration) XINE_PROTECTED; - - -/* - * plugin_loader functions - * - */ - -/* on-demand loading of audio/video/spu decoder plugins */ - -video_decoder_t *_x_get_video_decoder (xine_stream_t *stream, uint8_t stream_type) XINE_PROTECTED; -void _x_free_video_decoder (xine_stream_t *stream, video_decoder_t *decoder) XINE_PROTECTED; -audio_decoder_t *_x_get_audio_decoder (xine_stream_t *stream, uint8_t stream_type) XINE_PROTECTED; -void _x_free_audio_decoder (xine_stream_t *stream, audio_decoder_t *decoder) XINE_PROTECTED; -spu_decoder_t *_x_get_spu_decoder (xine_stream_t *stream, uint8_t stream_type) XINE_PROTECTED; -void _x_free_spu_decoder (xine_stream_t *stream, spu_decoder_t *decoder) XINE_PROTECTED; -/* check for decoder availability - but don't try to initialize it */ -int _x_decoder_available (xine_t *xine, uint32_t buftype) XINE_PROTECTED; - -/* - * load_video_output_plugin - * - * load a specific video output plugin - */ - -vo_driver_t *_x_load_video_output_plugin(xine_t *this, - char *id, int visual_type, void *visual) XINE_PROTECTED; - -/* - * audio output plugin dynamic loading stuff - */ - -/* - * load_audio_output_plugin - * - * load a specific audio output plugin - */ - -ao_driver_t *_x_load_audio_output_plugin (xine_t *self, char *id) XINE_PROTECTED; - - -void _x_set_speed (xine_stream_t *stream, int speed) XINE_PROTECTED; - -int _x_get_speed (xine_stream_t *stream) XINE_PROTECTED; - -void _x_set_fine_speed (xine_stream_t *stream, int speed) XINE_PROTECTED; - -int _x_get_fine_speed (xine_stream_t *stream) XINE_PROTECTED; - -void _x_select_spu_channel (xine_stream_t *stream, int channel) XINE_PROTECTED; - -int _x_get_audio_channel (xine_stream_t *stream) XINE_PROTECTED; - -int _x_get_spu_channel (xine_stream_t *stream) XINE_PROTECTED; - -/* - * internal events - */ - -/* sent by dvb frontend to inform ts demuxer of new pids */ -#define XINE_EVENT_PIDS_CHANGE 0x80000000 - -/* - * pids change event - inform ts demuxer of new pids - */ -typedef struct { - int vpid; /* video program id */ - int apid; /* audio program id */ -} xine_pids_data_t; - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/xine-engine/xine_plugin.h b/src/xine-engine/xine_plugin.h deleted file mode 100644 index 4ddb65eda..000000000 --- a/src/xine-engine/xine_plugin.h +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright (C) 2000-2003 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - * - * $Id: xine_plugin.h,v 1.23 2007/01/19 02:49:31 dgp85 Exp $ - * - * generic plugin definitions - * - */ - -#ifndef XINE_PLUGIN_H -#define XINE_PLUGIN_H - -#define PLUGIN_NONE 0 -#define PLUGIN_INPUT 1 -#define PLUGIN_DEMUX 2 -#define PLUGIN_AUDIO_DECODER 3 -#define PLUGIN_VIDEO_DECODER 4 -#define PLUGIN_SPU_DECODER 5 -#define PLUGIN_AUDIO_OUT 6 -#define PLUGIN_VIDEO_OUT 7 -#define PLUGIN_POST 8 - -#define PLUGIN_TYPE_MAX PLUGIN_POST - -/* this flag may be or'ed with type in order to force preloading the plugin. - * very useful to register config items on xine initialization. - */ -#define PLUGIN_MUST_PRELOAD (1 << 7) - -/* this flag may be or'ed with type to prevent the plugin loader from unloading - * the plugin - */ -#define PLUGIN_NO_UNLOAD (1 << 6) - -#define PLUGIN_TYPE_MASK ((1 << 6) - 1) - -typedef struct { - uint8_t type; /* one of the PLUGIN_* constants above */ - uint8_t API; /* API version supported by this plugin */ - char *id; /* a name that identifies this plugin */ - uint32_t version; /* version number, increased every release */ - const void *special_info; /* plugin-type specific, see structs below */ - void *(*init)(xine_t *, void *); /* init the plugin class */ -} plugin_info_t; - - -/* special_info for a video output plugin */ -typedef struct { - int priority; /* priority of this plugin for auto-probing */ - int visual_type; /* visual type supported by this plugin */ -} vo_info_t; - -/* special info for a audio output plugin */ -typedef struct { - int priority; -} ao_info_t; - -/* special_info for a decoder plugin */ -typedef struct { - uint32_t *supported_types; /* streamtypes this decoder can handle */ - int priority; -} decoder_info_t; - -/* special info for a post plugin */ -typedef struct { - uint32_t type; /* type of the post plugin, use one of XINE_POST_TYPE_* */ -} post_info_t; - -/* special info for a demuxer plugin */ -typedef struct { - int priority; -} demuxer_info_t; - -/* special info for an input plugin */ -typedef struct { - int priority; -} input_info_t; - - -/* register a list of statically linked plugins - * info is a list of plugin_info_t terminated by PLUGIN_NONE - * example: - * plugin_info_t acme_plugin_info[] = { - * { PLUGIN_VIDEO_OUT, 21, "acme", XINE_VERSION_CODE, &vo_info_acme, - * init_class_acme }, - * { PLUGIN_NONE, 0, "", 0, NULL, NULL } - * }; - * - */ -void xine_register_plugins(xine_t *self, plugin_info_t *info) XINE_PROTECTED; - -#endif diff --git a/src/xine-engine/xineintl.h b/src/xine-engine/xineintl.h deleted file mode 100644 index 614195193..000000000 --- a/src/xine-engine/xineintl.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (C) 2000-2005 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - * - * $Id: xineintl.h,v 1.9 2005/02/19 13:11:53 valtri Exp $ - * - */ - -#ifndef HAVE_XINEINTL_H -#define HAVE_XINEINTL_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include <locale.h> - -#ifdef ENABLE_NLS -# include <libintl.h> -# define _(String) dgettext (XINE_TEXTDOMAIN, String) -# ifdef gettext_noop -# define N_(String) gettext_noop (String) -# else -# define N_(String) (String) -# endif -#else -/* Stubs that do something close enough. */ -# define textdomain(String) (String) -# define gettext(String) (String) -# define dgettext(Domain,Message) (Message) -# define dcgettext(Domain,Message,Type) (Message) -# define ngettext(Singular, Plural, IsPlural) (Singular) -# define bindtextdomain(Domain,Directory) (Domain) -# define _(String) (String) -# define N_(String) (String) -#endif - -#ifdef __cplusplus -} -#endif - -#endif |