diff options
334 files changed, 7927 insertions, 5468 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000..411891e554 --- /dev/null +++ b/.gitignore @@ -0,0 +1,17 @@ +*.o +*.a +*.d +.depend + +/ffmpeg +/config.h +/config.mak +/configure.log +/help_mp.h +/mencoder +/mplayer +/version.h +/codecs.conf.h +/codec-cfg +/codec-cfg-test +/codecs2html diff --git a/DOCS/man/en/mplayer.1 b/DOCS/man/en/mplayer.1 index f1923d38a8..d0920e4a45 100644 --- a/DOCS/man/en/mplayer.1 +++ b/DOCS/man/en/mplayer.1 @@ -4244,8 +4244,6 @@ Each file takes the frame number padded with leading zeros as name. .IPs z=<0\-9> Specifies the compression level. 0 is no compression, 9 is maximum compression. -.IPs outdir=<dirname> -Specify the directory to save the PNG files to (default: ./). .IPs alpha (default: noalpha) Create PNG files with an alpha channel. Note that MPlayer in general does not support alpha, so this will only diff --git a/DOCS/man/fr/mplayer.1 b/DOCS/man/fr/mplayer.1 index 5a203fcf4a..6cd246408d 100644 --- a/DOCS/man/fr/mplayer.1 +++ b/DOCS/man/fr/mplayer.1 @@ -4482,8 +4482,6 @@ Ne gère que les formats RGB et BGR 24 bits/pixel. .IPs z=<0\-9> Définit le taux de compression. 0 équivaut à pas de compression et 9 à la compression maximale. -.IPs outdir=<chemin> -Définit le répertoire où sauver les fichiers PNG (par défaut\ ./). .IPs alpha (par défaut\ : noalpha) Crée un fichier PNG avec un canal alpha. Notez que MPlayer ne gère en général pas les canaux alpha, donc cette diff --git a/DOCS/tech/libmpcodecs.txt b/DOCS/tech/libmpcodecs.txt index 22d29aaf98..5015f5dcc0 100644 --- a/DOCS/tech/libmpcodecs.txt +++ b/DOCS/tech/libmpcodecs.txt @@ -153,7 +153,7 @@ vf_info_t* info; const char *name; // short name of the filter, must be FILTERNAME const char *author; // name and email/URL of the author(s) const char *comment; // comment, URL to papers describing algorithm etc. - int (*open)(struct vf_instance_s* vf,char* args); + int (*open)(struct vf_instance* vf,char* args); // pointer to the open() function: Sample: @@ -197,13 +197,13 @@ static int open(vf_instance_t *vf, char* args) return 1; } -Functions in vf_instance_s: +Functions in vf_instance: NOTE: All these are optional, their function pointer is either NULL or points to a default implementation. If you implement them, don't forget to set vf->FUNCNAME in your open() ! - int (*query_format)(struct vf_instance_s* vf, unsigned int fmt); + int (*query_format)(struct vf_instance* vf, unsigned int fmt); The query_format() function is called one or more times before the config(), to find out the capabilities and/or support status of a given colorspace (fmt). @@ -216,7 +216,7 @@ next filter will accept at least one of your possible output colorspaces! Sample: -static int query_format(struct vf_instance_s* vf, unsigned int fmt) +static int query_format(struct vf_instance* vf, unsigned int fmt) { switch(fmt){ case IMGFMT_YV12: @@ -232,7 +232,7 @@ For the more complex case, when you have an N -> M colorspace mapping matrix, see vf_scale or vf_rgb2bgr for examples. - int (*config)(struct vf_instance_s* vf, + int (*config)(struct vf_instance* vf, int width, int height, int d_width, int d_height, unsigned int flags, unsigned int outfmt); @@ -257,7 +257,7 @@ Its parameters are already well-known from libvo: Sample: -static int config(struct vf_instance_s* vf, +static int config(struct vf_instance* vf, int width, int height, int d_width, int d_height, unsigned int flags, unsigned int outfmt) { @@ -272,12 +272,12 @@ static int config(struct vf_instance_s* vf, return vf_next_config(vf,vf->priv->w,vf->priv->h,d_width,d_height,flags,outfmt); } - void (*uninit)(struct vf_instance_s* vf); + void (*uninit)(struct vf_instance* vf); Okay, uninit() is the simplest, it's called at the end. You can free your private buffers etc here. - int (*put_image)(struct vf_instance_s* vf, mp_image_t *mpi); + int (*put_image)(struct vf_instance* vf, mp_image_t *mpi); Ah, put_image(). This is the main filter function, it should convert/filter/ transform the image data from one format/size/color/whatever to another. @@ -332,7 +332,7 @@ image: Ok, the rest is for advanced functionality only: - int (*control)(struct vf_instance_s* vf, int request, void* data); + int (*control)(struct vf_instance* vf, int request, void* data); You can control the filter at runtime from MPlayer/MEncoder/dec_video: #define VFCTRL_QUERY_MAX_PP_LEVEL 4 /* test for postprocessing support (max level) */ @@ -343,7 +343,7 @@ You can control the filter at runtime from MPlayer/MEncoder/dec_video: #define VFCTRL_CHANGE_RECTANGLE 9 /* Change the rectangle boundaries */ - void (*get_image)(struct vf_instance_s* vf, mp_image_t *mpi); + void (*get_image)(struct vf_instance* vf, mp_image_t *mpi); This is for direct rendering support, works the same way as in libvo drivers. It makes in-place pixel modifications possible. @@ -359,7 +359,7 @@ order, while put_image is called for display) so the only safe place to save it is in the mpi struct itself: mpi->priv=(void*)dmpi; - void (*draw_slice)(struct vf_instance_s* vf, unsigned char** src, + void (*draw_slice)(struct vf_instance* vf, unsigned char** src, int* stride, int w,int h, int x, int y); It's the good old draw_slice callback, already known from libvo. @@ -36,6 +36,7 @@ LDFLAGS_MENCODER = $(EXTRALIBS_MENCODER) \ SRCS_COMMON = asxparser.c \ codec-cfg.c \ cpudetect.c \ + defaultopts.c \ edl.c \ find_sub.c \ fmt-conversion.c \ @@ -51,6 +52,7 @@ SRCS_COMMON = asxparser.c \ sub_cc.c \ subopt-helper.c \ subreader.c \ + talloc.c \ vobsub.c \ libaf/af.c \ libaf/af_center.c \ @@ -528,6 +530,7 @@ SRCS_MPLAYER = mplayer.c \ libao2/ao_pcm.c \ libvo/aspect.c \ libvo/geometry.c \ + libvo/old_vo_wrapper.c \ libvo/spuenc.c \ libvo/video_out.c \ libvo/vo_mpegpes.c \ @@ -698,10 +701,10 @@ SRCS_COMMON += $(SRCS_COMMON-yes) $(SRCS_COMMON-yes-yes) $(SRCS_COMMON-yes-yes SRCS_MENCODER += $(SRCS_MENCODER-yes) SRCS_MPLAYER += $(SRCS_MPLAYER-yes) -COMMON_LIBS-$(LIBAVFORMAT_A) += libavformat/libavformat.a -COMMON_LIBS-$(LIBAVCODEC_A) += libavcodec/libavcodec.a -COMMON_LIBS-$(LIBAVUTIL_A) += libavutil/libavutil.a -COMMON_LIBS-$(LIBPOSTPROC_A) += libpostproc/libpostproc.a +COMMON_LIBS-$(LIBAVFORMAT_A) += ffmpeg/libavformat/libavformat.a +COMMON_LIBS-$(LIBAVCODEC_A) += ffmpeg/libavcodec/libavcodec.a +COMMON_LIBS-$(LIBAVUTIL_A) += ffmpeg/libavutil/libavutil.a +COMMON_LIBS-$(LIBPOSTPROC_A) += ffmpeg/libpostproc/libpostproc.a COMMON_LIBS-$(LIBSWSCALE_A) += libswscale/libswscale.a COMMON_LIBS += $(COMMON_LIBS-yes) @@ -734,17 +737,17 @@ DIRS = . \ libaf \ libao2 \ libass \ - libavcodec \ - libavcodec/alpha \ - libavcodec/arm \ - libavcodec/bfin \ - libavcodec/mlib \ - libavcodec/ppc \ - libavcodec/sh4 \ - libavcodec/sparc \ - libavcodec/x86 \ - libavformat \ - libavutil \ + ffmpeg/libavcodec \ + ffmpeg/libavcodec/alpha \ + ffmpeg/libavcodec/arm \ + ffmpeg/libavcodec/bfin \ + ffmpeg/libavcodec/x86 \ + ffmpeg/libavcodec/mlib \ + ffmpeg/libavcodec/ppc \ + ffmpeg/libavcodec/sh4 \ + ffmpeg/libavcodec/sparc \ + ffmpeg/libavformat \ + ffmpeg/libavutil \ libdvdcss \ libdvdnav \ libdvdnav/vm \ @@ -755,7 +758,7 @@ DIRS = . \ libmpcodecs/native \ libmpdemux \ libmpeg2 \ - libpostproc \ + ffmpeg/libpostproc \ libswscale \ libvo \ loader \ @@ -773,14 +776,14 @@ DIRS = . \ ALLHEADERS = $(foreach dir,$(DIRS),$(wildcard $(dir)/*.h)) -PARTS = libavcodec \ - libavformat \ - libavutil \ - libpostproc \ +PARTS = ffmpeg/libavcodec \ + ffmpeg/libavformat \ + ffmpeg/libavutil \ + ffmpeg/libpostproc \ libswscale \ -FFMPEGLIBS = $(foreach part, $(PARTS), $(part)/$(part).a) -FFMPEGFILES = $(foreach part, $(PARTS), $(part)/*.[chS] libavcodec/*/*.[chS]) +FFMPEGLIBS = $(foreach part, $(PARTS), $(part)/$(notdir $(part)).a) +FFMPEGFILES = $(foreach part, $(PARTS), $(part)/*.[choS]) ffmpeg/libavcodec/*/*.[choS] ffmpeg/libavcodec/*/*.asm @@ -788,21 +791,18 @@ FFMPEGFILES = $(foreach part, $(PARTS), $(part)/*.[chS] libavcodec/*/*.[chS]) all: $(ALL_PRG-yes) -%.d: %.c - $(MPDEPEND_CMD) > $@ +%.o: %.c + $(CC) $(CFLAGS) -c -o $@ -MD -MP -MF $*.d $< -%.d: %.cpp - $(MPDEPEND_CMD_CXX) > $@ +%.o: %.cpp + $(CXX) $(CXXFLAGS) -c -o $@ -MD -MP -MF $*.d $< -%.d: %.m - $(MPDEPEND_CMD) > $@ +%.o: %.m + $(CC) $(CFLAGS) -c -o $@ -MD -MP -MF $*.d $< %.ho: %.h $(CC) $(CFLAGS) -Wno-unused -c -o $@ -x c $< -%.o: %.m - $(CC) $(CFLAGS) -c -o $@ $< - %-rc.o: %.rc $(WINDRES) -I. $< $@ @@ -811,6 +811,10 @@ checkheaders: $(ALLHEADERS:.h=.ho) dep depend: $(DEPS) for part in $(PARTS); do $(MAKE) -C $$part depend; done +# dummy to prevent default build rules from being used for FFMPEGFILES +$(FFMPEGFILES): + echo "this shouldn't run" + $(FFMPEGLIBS): $(FFMPEGFILES) config.h $(MAKE) -C $(@D) touch $@ @@ -822,7 +826,7 @@ mplayer$(EXESUF): $(MPLAYER_DEPS) $(CC) -o $@ $^ $(LDFLAGS_MPLAYER) codec-cfg$(EXESUF): codec-cfg.c codec-cfg.h help_mp.h - $(HOST_CC) -O -DCODECS2HTML $(EXTRA_INC) -o $@ $< + $(HOST_CC) -O -DCODECS2HTML -I. -Iffmpeg -o $@ $< codecs.conf.h: codec-cfg$(EXESUF) etc/codecs.conf ./$^ > $@ @@ -849,8 +853,8 @@ version.h: version.sh ###### dependency declarations / specific CFLAGS ###### -codec-cfg.d: codecs.conf.h -mpcommon.d vobsub.d gui/win32/gui.d libmpdemux/muxer_avi.d osdep/mplayer-rc.o stream/network.d stream/stream_cddb.d: version.h +codec-cfg.o: codecs.conf.h +mpcommon.o vobsub.o gui/win32/gui.o libmpdemux/muxer_avi.o osdep/mplayer-rc.o stream/network.o stream/stream_cddb.o: version.h $(DEPS): help_mp.h libdvdcss/%.o libdvdcss/%.d: CFLAGS += -D__USE_UNIX98 -D_GNU_SOURCE -DVERSION=\"1.2.10\" $(CFLAGS_LIBDVDCSS) @@ -886,7 +890,9 @@ $(VIDIX_DEPS) $(VIDIX_OBJS): $(VIDIX_PCI_FILES) install: $(INSTALL_TARGETS-yes) install-dirs: - $(INSTALL) -d $(BINDIR) $(CONFDIR) $(LIBDIR) + if test ! -d $(BINDIR) ; then $(INSTALL) -d $(BINDIR) ; fi + if test ! -d $(CONFDIR) ; then $(INSTALL) -d $(CONFDIR) ; fi + if test ! -d $(LIBDIR) ; then $(INSTALL) -d $(LIBDIR) ; fi install-%: %$(EXESUF) install-dirs $(INSTALL) -m 755 $(INSTALLSTRIP) $< $(BINDIR) @@ -904,7 +910,7 @@ install-mencoder-man-en: install-mplayer-man-en cd $(MANDIR)/man1 && ln -sf mplayer.1 mencoder.1 install-mplayer-man-en: - $(INSTALL) -d $(MANDIR)/man1 + if test ! -d $(MANDIR)/man1 ; then $(INSTALL) -d $(MANDIR)/man1 ; fi $(INSTALL) -m 644 DOCS/man/en/mplayer.1 $(MANDIR)/man1/ define MENCODER_MAN_RULE @@ -914,7 +920,7 @@ endef define MPLAYER_MAN_RULE install-mplayer-man-$(lang): - $(INSTALL) -d $(MANDIR)/$(lang)/man1 + if test ! -d $(MANDIR)/$(lang)/man1 ; then $(INSTALL) -d $(MANDIR)/$(lang)/man1 ; fi $(INSTALL) -m 644 DOCS/man/$(lang)/mplayer.1 $(MANDIR)/$(lang)/man1/ endef diff --git a/asxparser.c b/asxparser.c index cf72875886..554a006929 100644 --- a/asxparser.c +++ b/asxparser.c @@ -14,8 +14,6 @@ #include "mp_msg.h" #include "m_config.h" -extern m_config_t* mconfig; - ////// List utils void @@ -109,8 +107,10 @@ asx_attrib_to_enum(const char* val,char** valid_vals) { #define asx_warning_body_parse_error(p,e) mp_msg(MSGT_PLAYTREE,MSGL_WARN,"At line %d : error while parsing %s body",p->line,e) ASX_Parser_t* -asx_parser_new(void) { +asx_parser_new(struct m_config *mconfig) +{ ASX_Parser_t* parser = calloc(1,sizeof(ASX_Parser_t)); + parser->mconfig = mconfig; return parser; } @@ -426,7 +426,7 @@ asx_parse_param(ASX_Parser_t* parser, char** attribs, play_tree_t* pt) { return; } val = asx_get_attrib("VALUE",attribs); - if(m_config_get_option(mconfig,name) == NULL) { + if(m_config_get_option(parser->mconfig,name) == NULL) { mp_msg(MSGT_PLAYTREE,MSGL_WARN,"Found unknown param in asx: %s",name); if(val) mp_msg(MSGT_PLAYTREE,MSGL_WARN,"=%s\n",val); @@ -494,7 +494,7 @@ asx_parse_entryref(ASX_Parser_t* parser,char* buffer,char** _attribs) { mp_msg(MSGT_PLAYTREE,MSGL_V,"Adding playlist %s to element entryref\n",href); - ptp = play_tree_parser_new(stream,parser->deep+1); + ptp = play_tree_parser_new(stream, parser->mconfig, parser->deep+1); pt = play_tree_parser_get_play_tree(ptp, 1); @@ -611,11 +611,11 @@ asx_parse_repeat(ASX_Parser_t* parser,char* buffer,char** _attribs) { play_tree_t* -asx_parser_build_tree(char* buffer,int deep) { +asx_parser_build_tree(struct m_config *mconfig, char* buffer,int deep) { char *element,*asx_body,**asx_attribs,*body = NULL, **attribs; int r; play_tree_t *asx,*entry,*list = NULL; - ASX_Parser_t* parser = asx_parser_new(); + ASX_Parser_t* parser = asx_parser_new(mconfig); parser->line = 1; parser->deep = deep; diff --git a/asxparser.h b/asxparser.h index 2d9b860707..7b148a7775 100644 --- a/asxparser.h +++ b/asxparser.h @@ -14,10 +14,12 @@ struct ASX_Parser_t { int ret_stack_size; char* last_body; int deep; + struct m_config *mconfig; }; - + +struct m_config; ASX_Parser_t* -asx_parser_new(void); +asx_parser_new(struct m_config *mconfig); void asx_parser_free(ASX_Parser_t* parser); @@ -21,6 +21,7 @@ #include <stdlib.h> #include <string.h> +#include "av_opts.h" #include "libavcodec/opt.h" int parse_avopts(void *v, char *str){ diff --git a/cfg-common-opts.h b/cfg-common-opts.h index 13d3f386d3..34cb28a4fa 100644 --- a/cfg-common-opts.h +++ b/cfg-common-opts.h @@ -1,16 +1,9 @@ -#ifndef MPLAYER_CFG_COMMON_OPTS_H -#define MPLAYER_CFG_COMMON_OPTS_H - -#include "config.h" - -#include "osdep/priority.h" - // ------------------------- common options -------------------- {"quiet", &quiet, CONF_TYPE_FLAG, CONF_GLOBAL, 0, 1, NULL}, {"noquiet", &quiet, CONF_TYPE_FLAG, CONF_GLOBAL, 1, 0, NULL}, {"really-quiet", &verbose, CONF_TYPE_FLAG, CONF_GLOBAL|CONF_PRE_PARSE, 0, -10, NULL}, {"v", cfg_inc_verbose, CONF_TYPE_FUNC, CONF_GLOBAL|CONF_NOSAVE, 0, 0, NULL}, - {"msglevel", msgl_config, CONF_TYPE_SUBCONFIG, CONF_GLOBAL, 0, 0, NULL}, + {"msglevel", (void *) msgl_config, CONF_TYPE_SUBCONFIG, CONF_GLOBAL, 0, 0, NULL}, {"msgcolor", &mp_msg_color, CONF_TYPE_FLAG, CONF_GLOBAL, 0, 1, NULL}, {"nomsgcolor", &mp_msg_color, CONF_TYPE_FLAG, CONF_GLOBAL, 1, 0, NULL}, {"msgmodule", &mp_msg_module, CONF_TYPE_FLAG, CONF_GLOBAL, 0, 1, NULL}, @@ -18,11 +11,10 @@ #ifdef CONFIG_ICONV {"msgcharset", &mp_msg_charset, CONF_TYPE_STRING, CONF_GLOBAL, 0, 0, NULL}, #endif - {"include", cfg_include, CONF_TYPE_FUNC_PARAM, CONF_NOSAVE, 0, 0, NULL}, #ifdef CONFIG_PRIORITY {"priority", &proc_priority, CONF_TYPE_STRING, 0, 0, 0, NULL}, #endif - {"noconfig", noconfig_opts, CONF_TYPE_SUBCONFIG, CONF_GLOBAL|CONF_NOCFG|CONF_PRE_PARSE, 0, 0, NULL}, + {"noconfig", (void *) noconfig_opts, CONF_TYPE_SUBCONFIG, CONF_GLOBAL|CONF_NOCFG|CONF_PRE_PARSE, 0, 0, NULL}, // ------------------------- stream options -------------------- @@ -124,11 +116,11 @@ {"loadidx", &index_file_load, CONF_TYPE_STRING, 0, 0, 0, NULL}, // select audio/video/subtitle stream - {"aid", &audio_id, CONF_TYPE_INT, CONF_RANGE, 0, 8190, NULL}, + OPT_INTRANGE("aid", audio_id, 0, 0, 8190), {"ausid", &audio_substream_id, CONF_TYPE_INT, 0, 0, 0, NULL}, - {"vid", &video_id, CONF_TYPE_INT, CONF_RANGE, 0, 8190, NULL}, - {"sid", &dvdsub_id, CONF_TYPE_INT, CONF_RANGE, 0, 8190, NULL}, - {"novideo", &video_id, CONF_TYPE_FLAG, 0, -1, -2, NULL}, + OPT_INTRANGE("vid", video_id, 0, 0, 8190), + OPT_INTRANGE("sid", sub_id, 0, 0, 8190), + OPT_FLAG_CONSTANTS("novideo", video_id, 0, -1, -2), { "hr-mp3-seek", &hr_mp3_seek, CONF_TYPE_FLAG, 0, 0, 1, NULL }, { "nohr-mp3-seek", &hr_mp3_seek, CONF_TYPE_FLAG, 0, 1, 0, NULL}, @@ -150,25 +142,25 @@ { "extbased", &extension_parsing, CONF_TYPE_FLAG, 0, 0, 1, NULL }, { "noextbased", &extension_parsing, CONF_TYPE_FLAG, 0, 1, 0, NULL }, - {"mf", mfopts_conf, CONF_TYPE_SUBCONFIG, 0,0,0, NULL}, + {"mf", (void *) mfopts_conf, CONF_TYPE_SUBCONFIG, 0,0,0, NULL}, #ifdef CONFIG_RADIO {"radio", radioopts_conf, CONF_TYPE_SUBCONFIG, 0, 0, 0, NULL}, #else {"radio", "MPlayer was compiled without Radio interface support.\n", CONF_TYPE_PRINT, 0, 0, 0, NULL}, #endif /* CONFIG_RADIO */ #ifdef CONFIG_TV - {"tv", tvopts_conf, CONF_TYPE_SUBCONFIG, 0, 0, 0, NULL}, + {"tv", (void *) tvopts_conf, CONF_TYPE_SUBCONFIG, 0, 0, 0, NULL}, #else {"tv", "MPlayer was compiled without TV interface support.\n", CONF_TYPE_PRINT, 0, 0, 0, NULL}, #endif /* CONFIG_TV */ #ifdef CONFIG_PVR - {"pvr", pvropts_conf, CONF_TYPE_SUBCONFIG, 0, 0, 0, NULL}, + {"pvr", (void *) pvropts_conf, CONF_TYPE_SUBCONFIG, 0, 0, 0, NULL}, #else {"pvr", "MPlayer was compiled without V4L2/PVR interface support.\n", CONF_TYPE_PRINT, 0, 0, 0, NULL}, #endif /* CONFIG_PVR */ - {"vivo", vivoopts_conf, CONF_TYPE_SUBCONFIG, 0, 0, 0, NULL}, + {"vivo", (void *) vivoopts_conf, CONF_TYPE_SUBCONFIG, 0, 0, 0, NULL}, #ifdef CONFIG_DVBIN - {"dvbin", dvbin_opts_conf, CONF_TYPE_SUBCONFIG, 0, 0, 0, NULL}, + {"dvbin", (void *) dvbin_opts_conf, CONF_TYPE_SUBCONFIG, 0, 0, 0, NULL}, #endif // ------------------------- a-v sync options -------------------- @@ -185,7 +177,7 @@ {"srate", &force_srate, CONF_TYPE_INT, CONF_RANGE, 1000, 8*48000, NULL}, {"channels", &audio_output_channels, CONF_TYPE_INT, CONF_RANGE, 1, 6, NULL}, {"format", &audio_output_format, CONF_TYPE_AFMT, 0, 0, 0, NULL}, - {"speed", &playback_speed, CONF_TYPE_FLOAT, CONF_RANGE, 0.01, 100.0, NULL}, + OPT_FLOATRANGE("speed", playback_speed, 0, 0.01, 100.0), // set a-v distance {"delay", &audio_delay, CONF_TYPE_FLOAT, CONF_RANGE, -100.0, 100.0, NULL}, @@ -206,14 +198,14 @@ #endif // disable audio - {"sound", &audio_id, CONF_TYPE_FLAG, 0, -2, -1, NULL}, - {"nosound", &audio_id, CONF_TYPE_FLAG, 0, -1, -2, NULL}, + OPT_FLAG_CONSTANTS("sound", audio_id, 0, -2, -1), + OPT_FLAG_CONSTANTS("nosound", audio_id, 0, -1, -2), {"af*", &af_cfg.list, CONF_TYPE_STRING_LIST, 0, 0, 0, NULL}, - {"af-adv", audio_filter_conf, CONF_TYPE_SUBCONFIG, 0, 0, 0, NULL}, + {"af-adv", (void *) audio_filter_conf, CONF_TYPE_SUBCONFIG, 0, 0, 0, NULL}, {"vop", "-vop has been removed, use -vf instead.\n", CONF_TYPE_PRINT, CONF_NOCFG ,0,0, NULL}, - {"vf*", &vf_settings, CONF_TYPE_OBJ_SETTINGS_LIST, 0, 0, 0, &vf_obj_list}, + OPT_SETTINGSLIST("vf*", vf_settings, 0, &vf_obj_list), // select audio/video codec (by name) or codec family (by number): // {"afm", &audio_family, CONF_TYPE_INT, CONF_MIN, 0, 22, NULL}, // keep ranges in sync // {"vfm", &video_family, CONF_TYPE_INT, CONF_MIN, 0, 29, NULL}, // with codec-cfg.c @@ -234,15 +226,15 @@ // scaling: {"sws", &sws_flags, CONF_TYPE_INT, 0, 0, 2, NULL}, - {"ssf", scaler_filter_conf, CONF_TYPE_SUBCONFIG, 0, 0, 0, NULL}, - {"zoom", &softzoom, CONF_TYPE_FLAG, 0, 0, 1, NULL}, - {"nozoom", &softzoom, CONF_TYPE_FLAG, 0, 1, 0, NULL}, - {"aspect", &movie_aspect, CONF_TYPE_FLOAT, CONF_RANGE, 0.2, 3.0, NULL}, - {"noaspect", &movie_aspect, CONF_TYPE_FLAG, 0, 0, 0, NULL}, - {"xy", &screen_size_xy, CONF_TYPE_FLOAT, CONF_RANGE, 0.001, 4096, NULL}, - - {"flip", &flip, CONF_TYPE_FLAG, 0, -1, 1, NULL}, - {"noflip", &flip, CONF_TYPE_FLAG, 0, -1, 0, NULL}, + {"ssf", (void *) scaler_filter_conf, CONF_TYPE_SUBCONFIG, 0, 0, 0, NULL}, + OPT_FLAG_ON("zoom", softzoom, 0), + OPT_FLAG_OFF("nozoom", softzoom, 0), + OPT_FLOATRANGE("aspect", movie_aspect, 0, 0.2, 3.0), + OPT_FLAG_CONSTANTS("noaspect", movie_aspect, 0, 0, 0), + OPT_FLOATRANGE("xy", screen_size_xy, 0, 0.001, 4096), + + OPT_FLAG_CONSTANTS("flip", flip, 0, -1, 1), + OPT_FLAG_CONSTANTS("noflip", flip, 0, -1, 0), {"tsfastparse", "-tsfastparse is no longer a valid option.\n", CONF_TYPE_PRINT, CONF_NOCFG ,0,0, NULL }, {"tsprog", &ts_prog, CONF_TYPE_INT, CONF_RANGE, 0, 65534, NULL}, @@ -252,15 +244,15 @@ {"tskeepbroken", &ts_keep_broken, CONF_TYPE_FLAG, 0, 0, 1, NULL}, // draw by slices or whole frame (useful with libmpeg2/libavcodec) - {"slices", &vd_use_slices, CONF_TYPE_FLAG, 0, 0, 1, NULL}, - {"noslices", &vd_use_slices, CONF_TYPE_FLAG, 0, 1, 0, NULL}, + OPT_FLAG_ON("slices", vd_use_slices, 0), + OPT_FLAG_OFF("noslices", vd_use_slices, 0), {"field-dominance", &field_dominance, CONF_TYPE_INT, CONF_RANGE, -1, 1, NULL}, #ifdef CONFIG_LIBAVCODEC - {"lavdopts", lavc_decode_opts_conf, CONF_TYPE_SUBCONFIG, 0, 0, 0, NULL}, + {"lavdopts", (void *) lavc_decode_opts_conf, CONF_TYPE_SUBCONFIG, 0, 0, 0, NULL}, #endif #ifdef CONFIG_LIBAVFORMAT - {"lavfdopts", lavfdopts_conf, CONF_TYPE_SUBCONFIG, CONF_GLOBAL, 0, 0, NULL}, + {"lavfdopts", (void *) lavfdopts_conf, CONF_TYPE_SUBCONFIG, CONF_GLOBAL, 0, 0, NULL}, #endif #ifdef CONFIG_XVID4 {"xvidopts", xvid_dec_opts, CONF_TYPE_SUBCONFIG, 0, 0, 0, NULL}, @@ -346,5 +338,3 @@ {"fontconfig", "MPlayer was compiled without fontconfig support.\n", CONF_TYPE_PRINT, CONF_NOCFG, 0, 0, NULL}, {"nofontconfig", "MPlayer was compiled without fontconfig support.\n", CONF_TYPE_PRINT, CONF_NOCFG, 0, 0, NULL}, #endif /* CONFIG_FONTCONFIG */ - -#endif /* MPLAYER_CFG_COMMON_OPTS_H */ diff --git a/cfg-common.h b/cfg-common.h index ea5fce63f0..6db7ba069d 100644 --- a/cfg-common.h +++ b/cfg-common.h @@ -10,12 +10,6 @@ extern char *mp_msg_charset; extern int mp_msg_color; extern int mp_msg_module; -// codec/filter opts: (defined at libmpcodecs/vd.c) -extern float screen_size_xy; -extern float movie_aspect; -extern int softzoom; -extern int flip; - /* defined in codec-cfg.c */ extern char * codecs_file; @@ -229,7 +223,6 @@ extern int mf_w; extern int mf_h; extern double mf_fps; extern char * mf_type; -extern m_obj_settings_t* vf_settings; extern m_obj_list_t vf_obj_list; const m_option_t mfopts_conf[]={ diff --git a/cfg-mencoder.h b/cfg-mencoder.h index 36316ebfa0..5d09b45a3b 100644 --- a/cfg-mencoder.h +++ b/cfg-mencoder.h @@ -184,11 +184,11 @@ const m_option_t mencoder_opts[]={ {"xsize", "-xsize has been removed, use -vf crop=w:h:x:y for cropping.\n", CONF_TYPE_PRINT, CONF_NOCFG, 0, 0, NULL}, // output audio/video codec selection - {"oac", oac_conf, CONF_TYPE_SUBCONFIG, CONF_GLOBAL, 0, 0, NULL}, - {"ovc", ovc_conf, CONF_TYPE_SUBCONFIG, CONF_GLOBAL, 0, 0, NULL}, + {"oac", (void *) oac_conf, CONF_TYPE_SUBCONFIG, CONF_GLOBAL, 0, 0, NULL}, + {"ovc", (void *) ovc_conf, CONF_TYPE_SUBCONFIG, CONF_GLOBAL, 0, 0, NULL}, // output file format - {"of", of_conf, CONF_TYPE_SUBCONFIG, CONF_GLOBAL, 0, 0, NULL}, + {"of", (void *) of_conf, CONF_TYPE_SUBCONFIG, CONF_GLOBAL, 0, 0, NULL}, // override audio format tag in output file {"fafmttag", &force_audiofmttag, CONF_TYPE_INT, CONF_GLOBAL, 0, 0, NULL}, @@ -215,7 +215,7 @@ const m_option_t mencoder_opts[]={ {"noodml", &write_odml, CONF_TYPE_FLAG, CONF_GLOBAL, 1, 0, NULL}, // info header strings - {"info", info_conf, CONF_TYPE_SUBCONFIG, CONF_GLOBAL, 0, 0, NULL}, + {"info", (void *) info_conf, CONF_TYPE_SUBCONFIG, CONF_GLOBAL, 0, 0, NULL}, #ifdef CONFIG_MP3LAME {"lameopts", lameopts_conf, CONF_TYPE_SUBCONFIG, CONF_GLOBAL, 0, 0, NULL}, diff --git a/cfg-mplayer.h b/cfg-mplayer.h index 3cb810614f..8bcad6c9e0 100644 --- a/cfg-mplayer.h +++ b/cfg-mplayer.h @@ -5,10 +5,10 @@ * config for cfgparser */ -#include "cfg-common.h" +#include <stddef.h> -extern int key_fifo_size; -extern unsigned doubleclick_time; +#include "cfg-common.h" +#include "options.h" extern char *fb_mode_cfgfile; extern char *fb_mode_name; @@ -16,15 +16,9 @@ extern char *dfb_params; extern char *lirc_configfile; -extern float vo_panscanrange; /* only used at startup (setting these values from configfile) */ extern char *vo_geometry; -extern int opt_screen_size_x; -extern int opt_screen_size_y; -extern int fullscreen; -extern int vidmode; - extern char *ao_outputfilename; extern int ao_pcm_waveheader; @@ -49,10 +43,6 @@ extern char * skinName; extern int guiWinID; -/* from libvo/aspect.c */ -extern float force_monitor_aspect; -extern float monitor_pixel_aspect; - extern int sws_flags; int readPPOpt(void *conf, char *arg); void revertPPOpt(void *conf, char* opt); @@ -90,12 +80,12 @@ const m_option_t mplayer_opts[]={ //---------------------- libao/libvo options ------------------------ {"o", "Option -o has been renamed to -vo (video-out), use -vo.\n", CONF_TYPE_PRINT, CONF_NOCFG, 0, 0, NULL}, - {"vo", &video_driver_list, CONF_TYPE_STRING_LIST, 0, 0, 0, NULL}, - {"ao", &audio_driver_list, CONF_TYPE_STRING_LIST, 0, 0, 0, NULL}, - {"fixed-vo", &fixed_vo, CONF_TYPE_FLAG,CONF_GLOBAL , 0, 1, NULL}, - {"nofixed-vo", &fixed_vo, CONF_TYPE_FLAG,CONF_GLOBAL, 1, 0, NULL}, - {"ontop", &vo_ontop, CONF_TYPE_FLAG, 0, 0, 1, NULL}, - {"noontop", &vo_ontop, CONF_TYPE_FLAG, 0, 1, 0, NULL}, + OPT_STRINGLIST("vo", video_driver_list, 0), + OPT_STRINGLIST("ao", audio_driver_list, 0), + OPT_FLAG_ON("fixed-vo", fixed_vo, CONF_GLOBAL), + OPT_FLAG_OFF("nofixed-vo", fixed_vo, CONF_GLOBAL), + OPT_FLAG_ON("ontop", vo_ontop, 0), + OPT_FLAG_OFF("noontop", vo_ontop, 0), {"rootwin", &vo_rootwin, CONF_TYPE_FLAG, 0, 0, 1, NULL}, {"border", &vo_border, CONF_TYPE_FLAG, 0, 0, 1, NULL}, {"noborder", &vo_border, CONF_TYPE_FLAG, 0, 1, 0, NULL}, @@ -163,27 +153,27 @@ const m_option_t mplayer_opts[]={ #endif // force window width/height or resolution (with -vm) - {"x", &opt_screen_size_x, CONF_TYPE_INT, CONF_RANGE, 0, 4096, NULL}, - {"y", &opt_screen_size_y, CONF_TYPE_INT, CONF_RANGE, 0, 4096, NULL}, + OPT_INTRANGE("x", screen_size_x, 0, 0, 4096), + OPT_INTRANGE("y", screen_size_y, 0, 0, 4096), // set screen dimensions (when not detectable or virtual!=visible) - {"screenw", &vo_screenwidth, CONF_TYPE_INT, CONF_RANGE|CONF_OLD, 0, 4096, NULL}, - {"screenh", &vo_screenheight, CONF_TYPE_INT, CONF_RANGE|CONF_OLD, 0, 4096, NULL}, + OPT_INTRANGE("screenw", vo_screenwidth, CONF_OLD, 0, 4096), + OPT_INTRANGE("screenh", vo_screenheight, CONF_OLD, 0, 4096), // Geometry string {"geometry", &vo_geometry, CONF_TYPE_STRING, 0, 0, 0, NULL}, // set aspect ratio of monitor - useful for 16:9 TV-out - {"monitoraspect", &force_monitor_aspect, CONF_TYPE_FLOAT, CONF_RANGE, 0.0, 9.0, NULL}, - {"monitorpixelaspect", &monitor_pixel_aspect, CONF_TYPE_FLOAT, CONF_RANGE, 0.2, 9.0, NULL}, + OPT_FLOATRANGE("monitoraspect", force_monitor_aspect, 0, 0.0, 9.0), + OPT_FLOATRANGE("monitorpixelaspect", monitor_pixel_aspect, 0, 0.2, 9.0), // video mode switching: (x11,xv,dga) - {"vm", &vidmode, CONF_TYPE_FLAG, 0, 0, 1, NULL}, - {"novm", &vidmode, CONF_TYPE_FLAG, 0, 1, 0, NULL}, + OPT_FLAG_ON("vm", vidmode, 0), + OPT_FLAG_OFF("novm", vidmode, 0), // start in fullscreen mode: - {"fs", &fullscreen, CONF_TYPE_FLAG, 0, 0, 1, NULL}, - {"nofs", &fullscreen, CONF_TYPE_FLAG, 0, 1, 0, NULL}, + OPT_FLAG_ON("fs", fullscreen, 0), + OPT_FLAG_OFF("nofs", fullscreen, 0), // set fullscreen switch method (workaround for buggy WMs) {"fsmode", "-fsmode is obsolete, avoid it and use -fstype instead.\nIf you really want it, try -fsmode-dontuse, but don't report bugs!\n", CONF_TYPE_PRINT, CONF_RANGE, 0, 31, NULL}, {"fsmode-dontuse", &vo_fsmode, CONF_TYPE_INT, CONF_RANGE, 0, 31, NULL}, // set bpp (x11+vm, dga, fbdev, vesa, svga?) - {"bpp", &vo_dbpp, CONF_TYPE_INT, CONF_RANGE, 0, 32, NULL}, + OPT_INTRANGE("bpp", vo_dbpp, 0, 0, 32), {"colorkey", &vo_colorkey, CONF_TYPE_INT, 0, 0, 0, NULL}, {"nocolorkey", &vo_colorkey, CONF_TYPE_FLAG, 0, 0, 0x1000000, NULL}, {"double", &vo_doublebuffering, CONF_TYPE_FLAG, 0, 0, 1, NULL}, @@ -192,7 +182,7 @@ const m_option_t mplayer_opts[]={ {"vsync", &vo_vsync, CONF_TYPE_FLAG, 0, 0, 1, NULL}, {"novsync", &vo_vsync, CONF_TYPE_FLAG, 0, 1, 0, NULL}, {"panscan", &vo_panscan, CONF_TYPE_FLOAT, CONF_RANGE, -1.0, 1.0, NULL}, - {"panscanrange", &vo_panscanrange, CONF_TYPE_FLOAT, CONF_RANGE, -19.0, 99.0, NULL}, + OPT_FLOATRANGE("panscanrange", vo_panscanrange, 0, -19.0, 99.0), {"grabpointer", &vo_grabpointer, CONF_TYPE_FLAG, 0, 0, 1, NULL}, {"nograbpointer", &vo_grabpointer, CONF_TYPE_FLAG, 0, 1, 0, NULL}, @@ -214,10 +204,10 @@ const m_option_t mplayer_opts[]={ {"xineramascreen", &xinerama_screen, CONF_TYPE_INT, CONF_RANGE, -2, 32, NULL}, - {"brightness",&vo_gamma_brightness, CONF_TYPE_INT, CONF_RANGE, -100, 100, NULL}, - {"saturation",&vo_gamma_saturation, CONF_TYPE_INT, CONF_RANGE, -100, 100, NULL}, - {"contrast",&vo_gamma_contrast, CONF_TYPE_INT, CONF_RANGE, -100, 100, NULL}, - {"hue",&vo_gamma_hue, CONF_TYPE_INT, CONF_RANGE, -100, 100, NULL}, + OPT_INTRANGE("brightness", vo_gamma_brightness, 0, -100, 100), + OPT_INTRANGE("saturation", vo_gamma_saturation, 0, -100, 100), + OPT_INTRANGE("contrast", vo_gamma_contrast, 0, -100, 100), + OPT_INTRANGE("hue", vo_gamma_hue, 0, -100, 100), {"keepaspect", &vo_keepaspect, CONF_TYPE_FLAG, 0, 0, 1, NULL}, {"nokeepaspect", &vo_keepaspect, CONF_TYPE_FLAG, 0, 1, 0, NULL}, @@ -315,13 +305,13 @@ const m_option_t mplayer_opts[]={ {"guiwid", &guiWinID, CONF_TYPE_INT, 0, 0, 0, NULL}, #endif - {"noloop", &mpctx_s.loop_times, CONF_TYPE_FLAG, 0, 0, -1, NULL}, - {"loop", &mpctx_s.loop_times, CONF_TYPE_INT, CONF_RANGE, -1, 10000, NULL}, + OPT_FLAG_CONSTANTS("noloop", loop_times, 0, 0, -1), + OPT_INTRANGE("loop", loop_times, 0, -1, 10000), {"playlist", NULL, CONF_TYPE_STRING, 0, 0, 0, NULL}, // a-v sync stuff: - {"correct-pts", &user_correct_pts, CONF_TYPE_FLAG, 0, 0, 1, NULL}, - {"nocorrect-pts", &user_correct_pts, CONF_TYPE_FLAG, 0, 1, 0, NULL}, + OPT_FLAG_ON("correct-pts", user_correct_pts, 0), + OPT_FLAG_OFF("nocorrect-pts", user_correct_pts, 0), {"noautosync", &autosync, CONF_TYPE_FLAG, 0, 0, -1, NULL}, {"autosync", &autosync, CONF_TYPE_INT, CONF_RANGE, 0, 10000, NULL}, // {"dapsync", &dapsync, CONF_TYPE_FLAG, 0, 0, 1, NULL}, @@ -343,14 +333,14 @@ const m_option_t mplayer_opts[]={ {"idle", &player_idle_mode, CONF_TYPE_FLAG,CONF_GLOBAL , 0, 1, NULL}, {"noidle", &player_idle_mode, CONF_TYPE_FLAG,CONF_GLOBAL , 1, 0, NULL}, {"use-stdin", "-use-stdin has been renamed to -noconsolecontrols, use that instead.", CONF_TYPE_PRINT, 0, 0, 0, NULL}, - {"key-fifo-size", &key_fifo_size, CONF_TYPE_INT, CONF_RANGE, 2, 65000, NULL}, + OPT_INTRANGE("key-fifo-size", key_fifo_size, CONF_GLOBAL, 2, 65000), {"noconsolecontrols", &noconsolecontrols, CONF_TYPE_FLAG, CONF_GLOBAL, 0, 1, NULL}, {"consolecontrols", &noconsolecontrols, CONF_TYPE_FLAG, CONF_GLOBAL, 1, 0, NULL}, {"mouse-movements", &enable_mouse_movements, CONF_TYPE_FLAG, CONF_GLOBAL, 0, 1, NULL}, {"nomouse-movements", &enable_mouse_movements, CONF_TYPE_FLAG, CONF_GLOBAL, 1, 0, NULL}, - {"doubleclick-time", &doubleclick_time, CONF_TYPE_INT, CONF_RANGE, 0, 1000, NULL}, + OPT_INTRANGE("doubleclick-time", doubleclick_time, 0, 0, 1000), #ifdef CONFIG_TV - {"tvscan", tvscan_conf, CONF_TYPE_SUBCONFIG, 0, 0, 0, NULL}, + {"tvscan", (void *) tvscan_conf, CONF_TYPE_SUBCONFIG, 0, 0, 0, NULL}, #else {"tvscan", "MPlayer was compiled without TV interface support.\n", CONF_TYPE_PRINT, 0, 0, 0, NULL}, #endif /* CONFIG_TV */ @@ -363,7 +353,7 @@ const m_option_t mplayer_opts[]={ {"help", help_text, CONF_TYPE_PRINT, CONF_NOCFG|CONF_GLOBAL, 0, 0, NULL}, {"h", help_text, CONF_TYPE_PRINT, CONF_NOCFG|CONF_GLOBAL, 0, 0, NULL}, - {"vd", vd_conf, CONF_TYPE_SUBCONFIG, 0, 0, 0, NULL}, + {"vd", (void *) vd_conf, CONF_TYPE_SUBCONFIG, 0, 0, 0, NULL}, {NULL, NULL, 0, 0, 0, 0, NULL} }; diff --git a/codec-cfg.c b/codec-cfg.c index bb09f109fd..56dae05c45 100644 --- a/codec-cfg.c +++ b/codec-cfg.c @@ -24,6 +24,7 @@ #include <ctype.h> #include <assert.h> #include <string.h> +#include <stdint.h> #include "config.h" #include "mp_msg.h" @@ -37,9 +38,6 @@ #include "help_mp.h" -// for mmioFOURCC: -#include "libmpdemux/aviheader.h" - #include "libmpcodecs/img_format.h" #include "codec-cfg.h" @@ -47,6 +45,10 @@ #include "codecs.conf.h" #endif +#define mmioFOURCC( ch0, ch1, ch2, ch3 ) \ + ( (uint32_t)(uint8_t)(ch0) | ( (uint32_t)(uint8_t)(ch1) << 8 ) | \ + ( (uint32_t)(uint8_t)(ch2) << 16 ) | ( (uint32_t)(uint8_t)(ch3) << 24 ) ) + #define PRINT_LINENUM mp_msg(MSGT_CODECCFG,MSGL_ERR," at line %d\n", line_num) #define MAX_NR_TOKEN 16 diff --git a/codec-cfg.h b/codec-cfg.h index b9842d0a99..d964ef74db 100644 --- a/codec-cfg.h +++ b/codec-cfg.h @@ -38,7 +38,7 @@ typedef struct { #endif -typedef struct codecs_st { +typedef struct codecs { unsigned int fourcc[CODECS_MAX_FOURCC]; unsigned int fourccmap[CODECS_MAX_FOURCC]; unsigned int outfmt[CODECS_MAX_OUTFMT]; @@ -2,6 +2,7 @@ #include <inttypes.h> #include <unistd.h> #include <string.h> +#include <stdbool.h> #include "config.h" #include "command.h" @@ -18,6 +19,7 @@ #include "metadata.h" #include "libmpcodecs/vf.h" #include "libmpcodecs/vd.h" +#include "mp_osd.h" #include "libvo/video_out.h" #include "libvo/font_load.h" #include "playtree.h" @@ -66,35 +68,38 @@ extern int use_menu; -static void rescale_input_coordinates(int ix, int iy, double *dx, double *dy) +static void rescale_input_coordinates(struct MPContext *mpctx, int ix, int iy, + double *dx, double *dy) { + struct MPOpts *opts = &mpctx->opts; + struct vo *vo = mpctx->video_out; //remove the borders, if any, and rescale to the range [0,1],[0,1] if (vo_fs) { //we are in full-screen mode - if (vo_screenwidth > vo_dwidth) //there are borders along the x axis - ix -= (vo_screenwidth - vo_dwidth) / 2; - if (vo_screenheight > vo_dheight) //there are borders along the y axis (usual way) - iy -= (vo_screenheight - vo_dheight) / 2; + if (opts->vo_screenwidth > vo->dwidth) //there are borders along the x axis + ix -= (opts->vo_screenwidth - vo->dwidth) / 2; + if (opts->vo_screenheight > vo->dheight) //there are borders along the y axis (usual way) + iy -= (opts->vo_screenheight - vo->dheight) / 2; - if (ix < 0 || ix > vo_dwidth) { + if (ix < 0 || ix > vo->dwidth) { *dx = *dy = -1.0; return; } //we are on one of the borders - if (iy < 0 || iy > vo_dheight) { + if (iy < 0 || iy > vo->dheight) { *dx = *dy = -1.0; return; } //we are on one of the borders } - *dx = (double) ix / (double) vo_dwidth; - *dy = (double) iy / (double) vo_dheight; + *dx = (double) ix / (double) vo->dwidth; + *dy = (double) iy / (double) vo->dheight; mp_msg(MSGT_CPLAYER, MSGL_V, "\r\nrescaled coordinates: %.3lf, %.3lf, screen (%d x %d), vodisplay: (%d, %d), fullscreen: %d\r\n", - *dx, *dy, vo_screenwidth, vo_screenheight, vo_dwidth, - vo_dheight, vo_fs); + *dx, *dy, opts->vo_screenwidth, opts->vo_screenheight, vo->dwidth, + vo->dheight, vo_fs); } -static int sub_source_by_pos(MPContext * mpctx, int pos) +static int sub_source_by_pos(MPContext *mpctx, int pos) { int source = -1; int top = -1; @@ -109,7 +114,7 @@ static int sub_source_by_pos(MPContext * mpctx, int pos) return source; } -static int sub_source(MPContext * mpctx) +static int sub_source(MPContext *mpctx) { return sub_source_by_pos(mpctx, mpctx->global_sub_pos); } @@ -124,7 +129,7 @@ static int sub_source(MPContext * mpctx) * which need to be fixed while watching the movie. */ -static void log_sub(void) +static void log_sub(struct MPContext *mpctx) { char *fname; FILE *f; @@ -140,14 +145,14 @@ static void log_sub(void) if (subdata->sub_uses_time) { fprintf(f, "N: %s S: %02ld:%02ld:%02ld.%02ld E: %02ld:%02ld:%02ld.%02ld\n", - filename, vo_sub_last->start / 360000, + mpctx->filename, vo_sub_last->start / 360000, (vo_sub_last->start / 6000) % 60, (vo_sub_last->start / 100) % 60, vo_sub_last->start % 100, vo_sub_last->end / 360000, (vo_sub_last->end / 6000) % 60, (vo_sub_last->end / 100) % 60, vo_sub_last->end % 100); } else { - fprintf(f, "N: %s S: %ld E: %ld\n", filename, vo_sub_last->start, - vo_sub_last->end); + fprintf(f, "N: %s S: %ld E: %ld\n", mpctx->filename, + vo_sub_last->start, vo_sub_last->end); } for (i = 0; i < vo_sub_last->lines; i++) { fprintf(f, "%s\n", vo_sub_last->text[i]); @@ -164,77 +169,80 @@ static void log_sub(void) ///@{ /// OSD level (RW) -static int mp_property_osdlevel(m_option_t * prop, int action, void *arg, - MPContext * mpctx) +static int mp_property_osdlevel(m_option_t *prop, int action, void *arg, + MPContext *mpctx) { return m_property_choice(prop, action, arg, &osd_level); } /// Loop (RW) -static int mp_property_loop(m_option_t * prop, int action, void *arg, - MPContext * mpctx) +static int mp_property_loop(m_option_t *prop, int action, void *arg, + MPContext *mpctx) { + struct MPOpts *opts = &mpctx->opts; switch (action) { case M_PROPERTY_PRINT: if (!arg) return M_PROPERTY_ERROR; - if (mpctx->loop_times < 0) + if (opts->loop_times < 0) *(char**)arg = strdup("off"); - else if (mpctx->loop_times == 0) + else if (opts->loop_times == 0) *(char**)arg = strdup("inf"); else break; return M_PROPERTY_OK; } - return m_property_int_range(prop, action, arg, &mpctx->loop_times); + return m_property_int_range(prop, action, arg, &opts->loop_times); } /// Playback speed (RW) -static int mp_property_playback_speed(m_option_t * prop, int action, - void *arg, MPContext * mpctx) +static int mp_property_playback_speed(m_option_t *prop, int action, + void *arg, MPContext *mpctx) { + struct MPOpts *opts = &mpctx->opts; switch (action) { case M_PROPERTY_SET: if (!arg) return M_PROPERTY_ERROR; M_PROPERTY_CLAMP(prop, *(float *) arg); - playback_speed = *(float *) arg; - build_afilter_chain(mpctx->sh_audio, &ao_data); + opts->playback_speed = *(float *) arg; + build_afilter_chain(mpctx, mpctx->sh_audio, &ao_data); return M_PROPERTY_OK; case M_PROPERTY_STEP_UP: case M_PROPERTY_STEP_DOWN: - playback_speed += (arg ? *(float *) arg : 0.1) * + opts->playback_speed += (arg ? *(float *) arg : 0.1) * (action == M_PROPERTY_STEP_DOWN ? -1 : 1); - M_PROPERTY_CLAMP(prop, playback_speed); - build_afilter_chain(mpctx->sh_audio, &ao_data); + M_PROPERTY_CLAMP(prop, opts->playback_speed); + build_afilter_chain(mpctx, mpctx->sh_audio, &ao_data); return M_PROPERTY_OK; } - return m_property_float_range(prop, action, arg, &playback_speed); + return m_property_float_range(prop, action, arg, &opts->playback_speed); } /// filename with path (RO) -static int mp_property_path(m_option_t * prop, int action, void *arg, - MPContext * mpctx) +static int mp_property_path(m_option_t *prop, int action, void *arg, + MPContext *mpctx) { - return m_property_string_ro(prop, action, arg, filename); + return m_property_string_ro(prop, action, arg, mpctx->filename); } /// filename without path (RO) -static int mp_property_filename(m_option_t * prop, int action, void *arg, - MPContext * mpctx) +static int mp_property_filename(m_option_t *prop, int action, void *arg, + MPContext *mpctx) { char *f; - if (!filename) + if (!mpctx->filename) return M_PROPERTY_UNAVAILABLE; - if (((f = strrchr(filename, '/')) || (f = strrchr(filename, '\\'))) && f[1]) + if (((f = strrchr(mpctx->filename, '/')) + || (f = strrchr(mpctx->filename, '\\'))) && f[1]) f++; else - f = filename; + f = mpctx->filename; return m_property_string_ro(prop, action, arg, f); } /// Demuxer name (RO) -static int mp_property_demuxer(m_option_t * prop, int action, void *arg, - MPContext * mpctx) +static int mp_property_demuxer(m_option_t *prop, int action, void *arg, + MPContext *mpctx) { if (!mpctx->demuxer) return M_PROPERTY_UNAVAILABLE; @@ -243,8 +251,8 @@ static int mp_property_demuxer(m_option_t * prop, int action, void *arg, } /// Position in the stream (RW) -static int mp_property_stream_pos(m_option_t * prop, int action, void *arg, - MPContext * mpctx) +static int mp_property_stream_pos(m_option_t *prop, int action, void *arg, + MPContext *mpctx) { if (!mpctx->demuxer || !mpctx->demuxer->stream) return M_PROPERTY_UNAVAILABLE; @@ -263,8 +271,8 @@ static int mp_property_stream_pos(m_option_t * prop, int action, void *arg, } /// Stream start offset (RO) -static int mp_property_stream_start(m_option_t * prop, int action, - void *arg, MPContext * mpctx) +static int mp_property_stream_start(m_option_t *prop, int action, + void *arg, MPContext *mpctx) { if (!mpctx->demuxer || !mpctx->demuxer->stream) return M_PROPERTY_UNAVAILABLE; @@ -277,8 +285,8 @@ static int mp_property_stream_start(m_option_t * prop, int action, } /// Stream end offset (RO) -static int mp_property_stream_end(m_option_t * prop, int action, void *arg, - MPContext * mpctx) +static int mp_property_stream_end(m_option_t *prop, int action, void *arg, + MPContext *mpctx) { if (!mpctx->demuxer || !mpctx->demuxer->stream) return M_PROPERTY_UNAVAILABLE; @@ -291,8 +299,8 @@ static int mp_property_stream_end(m_option_t * prop, int action, void *arg, } /// Stream length (RO) -static int mp_property_stream_length(m_option_t * prop, int action, - void *arg, MPContext * mpctx) +static int mp_property_stream_length(m_option_t *prop, int action, + void *arg, MPContext *mpctx) { if (!mpctx->demuxer || !mpctx->demuxer->stream) return M_PROPERTY_UNAVAILABLE; @@ -306,8 +314,8 @@ static int mp_property_stream_length(m_option_t * prop, int action, } /// Media length in seconds (RO) -static int mp_property_length(m_option_t * prop, int action, void *arg, - MPContext * mpctx) +static int mp_property_length(m_option_t *prop, int action, void *arg, + MPContext *mpctx) { double len; @@ -319,8 +327,8 @@ static int mp_property_length(m_option_t * prop, int action, void *arg, } /// Current position in percent (RW) -static int mp_property_percent_pos(m_option_t * prop, int action, - void *arg, MPContext * mpctx) { +static int mp_property_percent_pos(m_option_t *prop, int action, + void *arg, MPContext *mpctx) { int pos; if (!mpctx->demuxer) @@ -344,14 +352,14 @@ static int mp_property_percent_pos(m_option_t * prop, int action, demuxer_get_percent_pos(mpctx->demuxer)); } - abs_seek_pos = SEEK_ABSOLUTE | SEEK_FACTOR; - rel_seek_secs = pos / 100.0; + mpctx->abs_seek_pos = SEEK_ABSOLUTE | SEEK_FACTOR; + mpctx->rel_seek_secs = pos / 100.0; return M_PROPERTY_OK; } /// Current position in seconds (RW) -static int mp_property_time_pos(m_option_t * prop, int action, - void *arg, MPContext * mpctx) { +static int mp_property_time_pos(m_option_t *prop, int action, + void *arg, MPContext *mpctx) { if (!(mpctx->sh_video || (mpctx->sh_audio && mpctx->audio_out))) return M_PROPERTY_UNAVAILABLE; @@ -359,20 +367,18 @@ static int mp_property_time_pos(m_option_t * prop, int action, case M_PROPERTY_SET: if(!arg) return M_PROPERTY_ERROR; M_PROPERTY_CLAMP(prop, *(double*)arg); - abs_seek_pos = SEEK_ABSOLUTE; - rel_seek_secs = *(double*)arg; + mpctx->abs_seek_pos = SEEK_ABSOLUTE; + mpctx->rel_seek_secs = *(double*)arg; return M_PROPERTY_OK; case M_PROPERTY_STEP_UP: case M_PROPERTY_STEP_DOWN: - rel_seek_secs += (arg ? *(double*)arg : 10.0) * + mpctx->rel_seek_secs += (arg ? *(double*)arg : 10.0) * (action == M_PROPERTY_STEP_UP ? 1.0 : -1.0); return M_PROPERTY_OK; } return m_property_time_ro(prop, action, arg, mpctx->sh_video ? mpctx->sh_video->pts : - playing_audio_pts(mpctx->sh_audio, - mpctx->d_audio, - mpctx->audio_out)); + playing_audio_pts(mpctx)); } /// Current chapter (RW) @@ -424,21 +430,21 @@ static int mp_property_chapter(m_option_t *prop, int action, void *arg, default: return M_PROPERTY_NOT_IMPLEMENTED; } - rel_seek_secs = 0; - abs_seek_pos = 0; + mpctx->rel_seek_secs = 0; + mpctx->abs_seek_pos = 0; chapter = demuxer_seek_chapter(mpctx->demuxer, chapter, 1, &next_pts, &chapter_num, &chapter_name); if (chapter >= 0) { if (next_pts > -1.0) { - abs_seek_pos = SEEK_ABSOLUTE; - rel_seek_secs = next_pts; + mpctx->abs_seek_pos = SEEK_ABSOLUTE; + mpctx->rel_seek_secs = next_pts; } if (chapter_name) set_osd_msg(OSD_MSG_TEXT, 1, osd_duration, MSGTR_OSDChapter, chapter + 1, chapter_name); } else if (step_all > 0) - rel_seek_secs = 1000000000.; + mpctx->rel_seek_secs = 1000000000.; else set_osd_msg(OSD_MSG_TEXT, 1, osd_duration, MSGTR_OSDChapter, 0, MSGTR_Unknown); @@ -521,11 +527,11 @@ static int mp_property_angle(m_option_t *prop, int action, void *arg, } /// Demuxer meta data -static int mp_property_metadata(m_option_t * prop, int action, void *arg, - MPContext * mpctx) { +static int mp_property_metadata(m_option_t *prop, int action, void *arg, + MPContext *mpctx) { m_property_action_t* ka; char* meta; - static m_option_t key_type = + static const m_option_t key_type = { "metadata", NULL, CONF_TYPE_STRING, 0, 0, 0, NULL }; if (!mpctx->demuxer) return M_PROPERTY_UNAVAILABLE; @@ -554,10 +560,31 @@ static int mp_property_metadata(m_option_t * prop, int action, void *arg, return M_PROPERTY_NOT_IMPLEMENTED; } -static int mp_property_pause(m_option_t * prop, int action, void *arg, - MPContext * mpctx) +static int mp_property_pause(m_option_t *prop, int action, void *arg, + void *ctx) { - return m_property_flag_ro(prop, action, arg, mpctx->osd_function == OSD_PAUSE); + MPContext *mpctx = ctx; + + switch (action) { + case M_PROPERTY_SET: + if (!arg) + return M_PROPERTY_ERROR; + if (mpctx->paused == (bool)*(int *) arg) + return M_PROPERTY_OK; + case M_PROPERTY_STEP_UP: + case M_PROPERTY_STEP_DOWN: + if (mpctx->paused) { + unpause_player(mpctx); + mpctx->osd_function = OSD_PLAY; + } + else { + pause_player(mpctx); + mpctx->osd_function = OSD_PAUSE; + } + return M_PROPERTY_OK; + default: + return m_property_flag(prop, action, arg, &mpctx->paused); + } } @@ -568,8 +595,8 @@ static int mp_property_pause(m_option_t * prop, int action, void *arg, ///@{ /// Volume (RW) -static int mp_property_volume(m_option_t * prop, int action, void *arg, - MPContext * mpctx) +static int mp_property_volume(m_option_t *prop, int action, void *arg, + MPContext *mpctx) { if (!mpctx->sh_audio) @@ -624,8 +651,8 @@ static int mp_property_volume(m_option_t * prop, int action, void *arg, } /// Mute (RW) -static int mp_property_mute(m_option_t * prop, int action, void *arg, - MPContext * mpctx) +static int mp_property_mute(m_option_t *prop, int action, void *arg, + MPContext *mpctx) { if (!mpctx->sh_audio) @@ -662,8 +689,8 @@ static int mp_property_mute(m_option_t * prop, int action, void *arg, } /// Audio delay (RW) -static int mp_property_audio_delay(m_option_t * prop, int action, - void *arg, MPContext * mpctx) +static int mp_property_audio_delay(m_option_t *prop, int action, + void *arg, MPContext *mpctx) { if (!(mpctx->sh_audio && mpctx->sh_video)) return M_PROPERTY_UNAVAILABLE; @@ -686,8 +713,8 @@ static int mp_property_audio_delay(m_option_t * prop, int action, } /// Audio codec tag (RO) -static int mp_property_audio_format(m_option_t * prop, int action, - void *arg, MPContext * mpctx) +static int mp_property_audio_format(m_option_t *prop, int action, + void *arg, MPContext *mpctx) { if (!mpctx->sh_audio) return M_PROPERTY_UNAVAILABLE; @@ -695,8 +722,8 @@ static int mp_property_audio_format(m_option_t * prop, int action, } /// Audio codec name (RO) -static int mp_property_audio_codec(m_option_t * prop, int action, - void *arg, MPContext * mpctx) +static int mp_property_audio_codec(m_option_t *prop, int action, + void *arg, MPContext *mpctx) { if (!mpctx->sh_audio || !mpctx->sh_audio->codec) return M_PROPERTY_UNAVAILABLE; @@ -704,8 +731,8 @@ static int mp_property_audio_codec(m_option_t * prop, int action, } /// Audio bitrate (RO) -static int mp_property_audio_bitrate(m_option_t * prop, int action, - void *arg, MPContext * mpctx) +static int mp_property_audio_bitrate(m_option_t *prop, int action, + void *arg, MPContext *mpctx) { if (!mpctx->sh_audio) return M_PROPERTY_UNAVAILABLE; @@ -713,8 +740,8 @@ static int mp_property_audio_bitrate(m_option_t * prop, int action, } /// Samplerate (RO) -static int mp_property_samplerate(m_option_t * prop, int action, void *arg, - MPContext * mpctx) +static int mp_property_samplerate(m_option_t *prop, int action, void *arg, + MPContext *mpctx) { if (!mpctx->sh_audio) return M_PROPERTY_UNAVAILABLE; @@ -729,8 +756,8 @@ static int mp_property_samplerate(m_option_t * prop, int action, void *arg, } /// Number of channels (RO) -static int mp_property_channels(m_option_t * prop, int action, void *arg, - MPContext * mpctx) +static int mp_property_channels(m_option_t *prop, int action, void *arg, + MPContext *mpctx) { if (!mpctx->sh_audio) return M_PROPERTY_UNAVAILABLE; @@ -755,8 +782,8 @@ static int mp_property_channels(m_option_t * prop, int action, void *arg, } /// Balance (RW) -static int mp_property_balance(m_option_t * prop, int action, void *arg, - MPContext * mpctx) +static int mp_property_balance(m_option_t *prop, int action, void *arg, + MPContext *mpctx) { float bal; @@ -806,9 +833,10 @@ static int mp_property_balance(m_option_t * prop, int action, void *arg, } /// Selected audio id (RW) -static int mp_property_audio(m_option_t * prop, int action, void *arg, - MPContext * mpctx) +static int mp_property_audio(m_option_t *prop, int action, void *arg, + MPContext *mpctx) { + struct MPOpts *opts = &mpctx->opts; int current_id = -1, tmp; switch (action) { @@ -817,7 +845,7 @@ static int mp_property_audio(m_option_t * prop, int action, void *arg, return M_PROPERTY_UNAVAILABLE; if (!arg) return M_PROPERTY_ERROR; - *(int *) arg = audio_id; + *(int *) arg = opts->audio_id; return M_PROPERTY_OK; case M_PROPERTY_PRINT: if (!mpctx->sh_audio) @@ -825,7 +853,7 @@ static int mp_property_audio(m_option_t * prop, int action, void *arg, if (!arg) return M_PROPERTY_ERROR; - if (audio_id < 0) + if (opts->audio_id < 0) *(char **) arg = strdup(MSGTR_Disabled); else { char lang[40] = MSGTR_Unknown; @@ -834,7 +862,7 @@ static int mp_property_audio(m_option_t * prop, int action, void *arg, av_strlcpy(lang, sh->lang, 40); #ifdef CONFIG_DVDREAD else if (mpctx->stream->type == STREAMTYPE_DVD) { - int code = dvd_lang_from_aid(mpctx->stream, audio_id); + int code = dvd_lang_from_aid(mpctx->stream, opts->audio_id); if (code) { lang[0] = code >> 8; lang[1] = code; @@ -845,10 +873,10 @@ static int mp_property_audio(m_option_t * prop, int action, void *arg, #ifdef CONFIG_DVDNAV else if (mpctx->stream->type == STREAMTYPE_DVDNAV) - mp_dvdnav_lang_from_aid(mpctx->stream, audio_id, lang); + mp_dvdnav_lang_from_aid(mpctx->stream, opts->audio_id, lang); #endif *(char **) arg = malloc(64); - snprintf(*(char **) arg, 64, "(%d) %s", audio_id, lang); + snprintf(*(char **) arg, 64, "(%d) %s", opts->audio_id, lang); } return M_PROPERTY_OK; @@ -861,21 +889,21 @@ static int mp_property_audio(m_option_t * prop, int action, void *arg, else tmp = -1; current_id = mpctx->demuxer->audio->id; - audio_id = demuxer_switch_audio(mpctx->demuxer, tmp); - if (audio_id == -2 - || (audio_id > -1 + opts->audio_id = demuxer_switch_audio(mpctx->demuxer, tmp); + if (opts->audio_id == -2 + || (opts->audio_id > -1 && mpctx->demuxer->audio->id != current_id && current_id != -2)) - uninit_player(INITIALIZED_AO | INITIALIZED_ACODEC); - if (audio_id > -1 && mpctx->demuxer->audio->id != current_id) { + uninit_player(mpctx, INITIALIZED_AO | INITIALIZED_ACODEC); + if (opts->audio_id > -1 && mpctx->demuxer->audio->id != current_id) { sh_audio_t *sh2; sh2 = mpctx->demuxer->a_streams[mpctx->demuxer->audio->id]; if (sh2) { sh2->ds = mpctx->demuxer->audio; mpctx->sh_audio = sh2; - reinit_audio_chain(); + reinit_audio_chain(mpctx); } } - mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_AUDIO_TRACK=%d\n", audio_id); + mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_AUDIO_TRACK=%d\n", opts->audio_id); return M_PROPERTY_OK; default: return M_PROPERTY_NOT_IMPLEMENTED; @@ -884,9 +912,10 @@ static int mp_property_audio(m_option_t * prop, int action, void *arg, } /// Selected video id (RW) -static int mp_property_video(m_option_t * prop, int action, void *arg, - MPContext * mpctx) +static int mp_property_video(m_option_t *prop, int action, void *arg, + MPContext *mpctx) { + struct MPOpts *opts = &mpctx->opts; int current_id = -1, tmp; switch (action) { @@ -895,7 +924,7 @@ static int mp_property_video(m_option_t * prop, int action, void *arg, return M_PROPERTY_UNAVAILABLE; if (!arg) return M_PROPERTY_ERROR; - *(int *) arg = video_id; + *(int *) arg = opts->video_id; return M_PROPERTY_OK; case M_PROPERTY_PRINT: if (!mpctx->sh_video) @@ -903,12 +932,12 @@ static int mp_property_video(m_option_t * prop, int action, void *arg, if (!arg) return M_PROPERTY_ERROR; - if (video_id < 0) + if (opts->video_id < 0) *(char **) arg = strdup(MSGTR_Disabled); else { char lang[40] = MSGTR_Unknown; *(char **) arg = malloc(64); - snprintf(*(char **) arg, 64, "(%d) %s", video_id, lang); + snprintf(*(char **) arg, 64, "(%d) %s", opts->video_id, lang); } return M_PROPERTY_OK; @@ -919,22 +948,22 @@ static int mp_property_video(m_option_t * prop, int action, void *arg, tmp = *((int *) arg); else tmp = -1; - video_id = demuxer_switch_video(mpctx->demuxer, tmp); - if (video_id == -2 - || (video_id > -1 && mpctx->demuxer->video->id != current_id + opts->video_id = demuxer_switch_video(mpctx->demuxer, tmp); + if (opts->video_id == -2 + || (opts->video_id > -1 && mpctx->demuxer->video->id != current_id && current_id != -2)) - uninit_player(INITIALIZED_VCODEC | - (fixed_vo && video_id != -2 ? 0 : INITIALIZED_VO)); - if (video_id > -1 && mpctx->demuxer->video->id != current_id) { + uninit_player(mpctx, INITIALIZED_VCODEC | + (mpctx->opts.fixed_vo && opts->video_id != -2 ? 0 : INITIALIZED_VO)); + if (opts->video_id > -1 && mpctx->demuxer->video->id != current_id) { sh_video_t *sh2; sh2 = mpctx->demuxer->v_streams[mpctx->demuxer->video->id]; if (sh2) { sh2->ds = mpctx->demuxer->video; mpctx->sh_video = sh2; - reinit_video_chain(); + reinit_video_chain(mpctx); } } - mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_VIDEO_TRACK=%d\n", video_id); + mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_VIDEO_TRACK=%d\n", opts->video_id); return M_PROPERTY_OK; default: @@ -942,8 +971,8 @@ static int mp_property_video(m_option_t * prop, int action, void *arg, } } -static int mp_property_program(m_option_t * prop, int action, void *arg, - MPContext * mpctx) +static int mp_property_program(m_option_t *prop, int action, void *arg, + MPContext *mpctx) { demux_program_t prog; @@ -975,8 +1004,8 @@ static int mp_property_program(m_option_t * prop, int action, void *arg, ///@{ /// Fullscreen state (RW) -static int mp_property_fullscreen(m_option_t * prop, int action, void *arg, - MPContext * mpctx) +static int mp_property_fullscreen(m_option_t *prop, int action, void *arg, + MPContext *mpctx) { if (!mpctx->video_out) @@ -996,16 +1025,16 @@ static int mp_property_fullscreen(m_option_t * prop, int action, void *arg, guiGetEvent(guiIEvent, (char *) MP_CMD_GUI_FULLSCREEN); else #endif - if (vo_config_count) - mpctx->video_out->control(VOCTRL_FULLSCREEN, 0); + if (mpctx->video_out->config_ok) + vo_control(mpctx->video_out, VOCTRL_FULLSCREEN, 0); return M_PROPERTY_OK; default: return m_property_flag(prop, action, arg, &vo_fs); } } -static int mp_property_deinterlace(m_option_t * prop, int action, - void *arg, MPContext * mpctx) +static int mp_property_deinterlace(m_option_t *prop, int action, + void *arg, MPContext *mpctx) { int deinterlace; vf_instance_t *vf; @@ -1035,12 +1064,12 @@ static int mp_property_deinterlace(m_option_t * prop, int action, } /// Panscan (RW) -static int mp_property_panscan(m_option_t * prop, int action, void *arg, - MPContext * mpctx) +static int mp_property_panscan(m_option_t *prop, int action, void *arg, + MPContext *mpctx) { if (!mpctx->video_out - || mpctx->video_out->control(VOCTRL_GET_PANSCAN, NULL) != VO_TRUE) + || vo_control(mpctx->video_out, VOCTRL_GET_PANSCAN, NULL) != VO_TRUE) return M_PROPERTY_UNAVAILABLE; switch (action) { @@ -1049,7 +1078,7 @@ static int mp_property_panscan(m_option_t * prop, int action, void *arg, return M_PROPERTY_ERROR; M_PROPERTY_CLAMP(prop, *(float *) arg); vo_panscan = *(float *) arg; - mpctx->video_out->control(VOCTRL_SET_PANSCAN, NULL); + vo_control(mpctx->video_out, VOCTRL_SET_PANSCAN, NULL); return M_PROPERTY_OK; case M_PROPERTY_STEP_UP: case M_PROPERTY_STEP_DOWN: @@ -1059,7 +1088,7 @@ static int mp_property_panscan(m_option_t * prop, int action, void *arg, vo_panscan = 1; else if (vo_panscan < 0) vo_panscan = 0; - mpctx->video_out->control(VOCTRL_SET_PANSCAN, NULL); + vo_control(mpctx->video_out, VOCTRL_SET_PANSCAN, NULL); return M_PROPERTY_OK; default: return m_property_float_range(prop, action, arg, &vo_panscan); @@ -1069,8 +1098,8 @@ static int mp_property_panscan(m_option_t * prop, int action, void *arg, /// Helper to set vo flags. /** \ingroup PropertyImplHelper */ -static int mp_property_vo_flag(m_option_t * prop, int action, void *arg, - int vo_ctrl, int *vo_var, MPContext * mpctx) +static int mp_property_vo_flag(m_option_t *prop, int action, void *arg, + int vo_ctrl, int *vo_var, MPContext *mpctx) { if (!mpctx->video_out) @@ -1085,8 +1114,8 @@ static int mp_property_vo_flag(m_option_t * prop, int action, void *arg, return M_PROPERTY_OK; case M_PROPERTY_STEP_UP: case M_PROPERTY_STEP_DOWN: - if (vo_config_count) - mpctx->video_out->control(vo_ctrl, 0); + if (mpctx->video_out->config_ok) + vo_control(mpctx->video_out, vo_ctrl, 0); return M_PROPERTY_OK; default: return m_property_flag(prop, action, arg, vo_var); @@ -1094,32 +1123,32 @@ static int mp_property_vo_flag(m_option_t * prop, int action, void *arg, } /// Window always on top (RW) -static int mp_property_ontop(m_option_t * prop, int action, void *arg, - MPContext * mpctx) +static int mp_property_ontop(m_option_t *prop, int action, void *arg, + MPContext *mpctx) { - return mp_property_vo_flag(prop, action, arg, VOCTRL_ONTOP, &vo_ontop, - mpctx); + return mp_property_vo_flag(prop, action, arg, VOCTRL_ONTOP, + &mpctx->opts.vo_ontop, mpctx); } /// Display in the root window (RW) -static int mp_property_rootwin(m_option_t * prop, int action, void *arg, - MPContext * mpctx) +static int mp_property_rootwin(m_option_t *prop, int action, void *arg, + MPContext *mpctx) { return mp_property_vo_flag(prop, action, arg, VOCTRL_ROOTWIN, &vo_rootwin, mpctx); } /// Show window borders (RW) -static int mp_property_border(m_option_t * prop, int action, void *arg, - MPContext * mpctx) +static int mp_property_border(m_option_t *prop, int action, void *arg, + MPContext *mpctx) { return mp_property_vo_flag(prop, action, arg, VOCTRL_BORDER, &vo_border, mpctx); } /// Framedropping state (RW) -static int mp_property_framedropping(m_option_t * prop, int action, - void *arg, MPContext * mpctx) +static int mp_property_framedropping(m_option_t *prop, int action, + void *arg, MPContext *mpctx) { if (!mpctx->sh_video) @@ -1139,10 +1168,11 @@ static int mp_property_framedropping(m_option_t * prop, int action, } /// Color settings, try to use vf/vo then fall back on TV. (RW) -static int mp_property_gamma(m_option_t * prop, int action, void *arg, - MPContext * mpctx) +static int mp_property_gamma(m_option_t *prop, int action, void *arg, + MPContext *mpctx) { - int *gamma = prop->priv, r, val; + int *gamma = (int *)((char *)&mpctx->opts + (int)prop->priv); + int r, val; if (!mpctx->sh_video) return M_PROPERTY_UNAVAILABLE; @@ -1196,15 +1226,15 @@ static int mp_property_gamma(m_option_t * prop, int action, void *arg, } /// VSync (RW) -static int mp_property_vsync(m_option_t * prop, int action, void *arg, - MPContext * mpctx) +static int mp_property_vsync(m_option_t *prop, int action, void *arg, + MPContext *mpctx) { return m_property_flag(prop, action, arg, &vo_vsync); } /// Video codec tag (RO) -static int mp_property_video_format(m_option_t * prop, int action, - void *arg, MPContext * mpctx) +static int mp_property_video_format(m_option_t *prop, int action, + void *arg, MPContext *mpctx) { char* meta; if (!mpctx->sh_video) @@ -1238,8 +1268,8 @@ static int mp_property_video_format(m_option_t * prop, int action, } /// Video codec name (RO) -static int mp_property_video_codec(m_option_t * prop, int action, - void *arg, MPContext * mpctx) +static int mp_property_video_codec(m_option_t *prop, int action, + void *arg, MPContext *mpctx) { if (!mpctx->sh_video || !mpctx->sh_video->codec) return M_PROPERTY_UNAVAILABLE; @@ -1248,8 +1278,8 @@ static int mp_property_video_codec(m_option_t * prop, int action, /// Video bitrate (RO) -static int mp_property_video_bitrate(m_option_t * prop, int action, - void *arg, MPContext * mpctx) +static int mp_property_video_bitrate(m_option_t *prop, int action, + void *arg, MPContext *mpctx) { if (!mpctx->sh_video) return M_PROPERTY_UNAVAILABLE; @@ -1257,8 +1287,8 @@ static int mp_property_video_bitrate(m_option_t * prop, int action, } /// Video display width (RO) -static int mp_property_width(m_option_t * prop, int action, void *arg, - MPContext * mpctx) +static int mp_property_width(m_option_t *prop, int action, void *arg, + MPContext *mpctx) { if (!mpctx->sh_video) return M_PROPERTY_UNAVAILABLE; @@ -1266,8 +1296,8 @@ static int mp_property_width(m_option_t * prop, int action, void *arg, } /// Video display height (RO) -static int mp_property_height(m_option_t * prop, int action, void *arg, - MPContext * mpctx) +static int mp_property_height(m_option_t *prop, int action, void *arg, + MPContext *mpctx) { if (!mpctx->sh_video) return M_PROPERTY_UNAVAILABLE; @@ -1275,8 +1305,8 @@ static int mp_property_height(m_option_t * prop, int action, void *arg, } /// Video fps (RO) -static int mp_property_fps(m_option_t * prop, int action, void *arg, - MPContext * mpctx) +static int mp_property_fps(m_option_t *prop, int action, void *arg, + MPContext *mpctx) { if (!mpctx->sh_video) return M_PROPERTY_UNAVAILABLE; @@ -1284,8 +1314,8 @@ static int mp_property_fps(m_option_t * prop, int action, void *arg, } /// Video aspect (RO) -static int mp_property_aspect(m_option_t * prop, int action, void *arg, - MPContext * mpctx) +static int mp_property_aspect(m_option_t *prop, int action, void *arg, + MPContext *mpctx) { if (!mpctx->sh_video) return M_PROPERTY_UNAVAILABLE; @@ -1299,8 +1329,8 @@ static int mp_property_aspect(m_option_t * prop, int action, void *arg, ///@{ /// Text subtitle position (RW) -static int mp_property_sub_pos(m_option_t * prop, int action, void *arg, - MPContext * mpctx) +static int mp_property_sub_pos(m_option_t *prop, int action, void *arg, + MPContext *mpctx) { if (!mpctx->sh_video) return M_PROPERTY_UNAVAILABLE; @@ -1318,9 +1348,10 @@ static int mp_property_sub_pos(m_option_t * prop, int action, void *arg, } /// Selected subtitles (RW) -static int mp_property_sub(m_option_t * prop, int action, void *arg, - MPContext * mpctx) +static int mp_property_sub(m_option_t *prop, int action, void *arg, + MPContext *mpctx) { + struct MPOpts *opts = &mpctx->opts; demux_stream_t *const d_sub = mpctx->d_sub; const int global_sub_size = mpctx->global_sub_size; int source = -1, reset_spu = 0; @@ -1361,10 +1392,10 @@ static int mp_property_sub(m_option_t * prop, int action, void *arg, } #ifdef CONFIG_DVDNAV if (mpctx->stream->type == STREAMTYPE_DVDNAV) { - if (vo_spudec && dvdsub_id >= 0) { + if (vo_spudec && opts->sub_id >= 0) { unsigned char lang[3]; - if (mp_dvdnav_lang_from_sid(mpctx->stream, dvdsub_id, lang)) { - snprintf(*(char **) arg, 63, "(%d) %s", dvdsub_id, lang); + if (mp_dvdnav_lang_from_sid(mpctx->stream, opts->sub_id, lang)) { + snprintf(*(char **) arg, 63, "(%d) %s", opts->sub_id, lang); return M_PROPERTY_OK; } } @@ -1375,10 +1406,10 @@ static int mp_property_sub(m_option_t * prop, int action, void *arg, || mpctx->demuxer->type == DEMUXER_TYPE_LAVF || mpctx->demuxer->type == DEMUXER_TYPE_LAVF_PREFERRED || mpctx->demuxer->type == DEMUXER_TYPE_OGG) - && d_sub && d_sub->sh && dvdsub_id >= 0) { + && d_sub && d_sub->sh && opts->sub_id >= 0) { const char* lang = ((sh_sub_t*)d_sub->sh)->lang; if (!lang) lang = MSGTR_Unknown; - snprintf(*(char **) arg, 63, "(%d) %s", dvdsub_id, lang); + snprintf(*(char **) arg, 63, "(%d) %s", opts->sub_id, lang); return M_PROPERTY_OK; } @@ -1391,18 +1422,18 @@ static int mp_property_sub(m_option_t * prop, int action, void *arg, } #ifdef CONFIG_DVDREAD if (vo_spudec && mpctx->stream->type == STREAMTYPE_DVD - && dvdsub_id >= 0) { + && opts->sub_id >= 0) { char lang[3]; - int code = dvd_lang_from_sid(mpctx->stream, dvdsub_id); + int code = dvd_lang_from_sid(mpctx->stream, opts->sub_id); lang[0] = code >> 8; lang[1] = code; lang[2] = 0; - snprintf(*(char **) arg, 63, "(%d) %s", dvdsub_id, lang); + snprintf(*(char **) arg, 63, "(%d) %s", opts->sub_id, lang); return M_PROPERTY_OK; } #endif - if (dvdsub_id >= 0) { - snprintf(*(char **) arg, 63, "(%d) %s", dvdsub_id, MSGTR_Unknown); + if (opts->sub_id >= 0) { + snprintf(*(char **) arg, 63, "(%d) %s", opts->sub_id, MSGTR_Unknown); return M_PROPERTY_OK; } snprintf(*(char **) arg, 63, MSGTR_Disabled); @@ -1446,7 +1477,7 @@ static int mp_property_sub(m_option_t * prop, int action, void *arg, subdata = NULL; vobsub_id = -1; - dvdsub_id = -1; + opts->sub_id = -1; if (d_sub) { if (d_sub->id > -2) reset_spu = 1; @@ -1471,17 +1502,17 @@ static int mp_property_sub(m_option_t * prop, int action, void *arg, vo_osd_changed(OSDTYPE_SUBTITLE); } } else if (source == SUB_SOURCE_DEMUX) { - dvdsub_id = + opts->sub_id = mpctx->global_sub_pos - mpctx->global_sub_indices[SUB_SOURCE_DEMUX]; - if (d_sub && dvdsub_id < MAX_S_STREAMS) { + if (d_sub && opts->sub_id < MAX_S_STREAMS) { int i = 0; // default: assume 1:1 mapping of sid and stream id - d_sub->id = dvdsub_id; + d_sub->id = opts->sub_id; d_sub->sh = mpctx->demuxer->s_streams[d_sub->id]; ds_free_packs(d_sub); for (i = 0; i < MAX_S_STREAMS; i++) { sh_sub_t *sh = mpctx->demuxer->s_streams[i]; - if (sh && sh->sid == dvdsub_id) { + if (sh && sh->sid == opts->sub_id) { d_sub->id = i; d_sub->sh = sh; break; @@ -1490,7 +1521,7 @@ static int mp_property_sub(m_option_t * prop, int action, void *arg, if (d_sub->sh && d_sub->id >= 0) { sh_sub_t *sh = d_sub->sh; if (sh->type == 'v') - init_vo_spudec(); + init_vo_spudec(mpctx); #ifdef CONFIG_ASS else if (ass_enabled) ass_track = sh->ass_track; @@ -1505,9 +1536,9 @@ static int mp_property_sub(m_option_t * prop, int action, void *arg, if (vo_spudec && (mpctx->stream->type == STREAMTYPE_DVD || mpctx->stream->type == STREAMTYPE_DVDNAV) - && dvdsub_id < 0 && reset_spu) { - dvdsub_id = -2; - d_sub->id = dvdsub_id; + && opts->sub_id < 0 && reset_spu) { + opts->sub_id = -2; + d_sub->id = opts->sub_id; } #endif update_subtitles(mpctx->sh_video, d_sub, 1); @@ -1516,8 +1547,8 @@ static int mp_property_sub(m_option_t * prop, int action, void *arg, } /// Selected sub source (RW) -static int mp_property_sub_source(m_option_t * prop, int action, void *arg, - MPContext * mpctx) +static int mp_property_sub_source(m_option_t *prop, int action, void *arg, + MPContext *mpctx) { int source; if (!mpctx->sh_video || mpctx->global_sub_size <= 0) @@ -1594,8 +1625,8 @@ static int mp_property_sub_source(m_option_t * prop, int action, void *arg, } /// Selected subtitles from specific source (RW) -static int mp_property_sub_by_type(m_option_t * prop, int action, void *arg, - MPContext * mpctx) +static int mp_property_sub_by_type(m_option_t *prop, int action, void *arg, + MPContext *mpctx) { int source, is_cur_source, offset; if (!mpctx->sh_video || mpctx->global_sub_size <= 0) @@ -1694,8 +1725,8 @@ static int mp_property_sub_by_type(m_option_t * prop, int action, void *arg, } /// Subtitle delay (RW) -static int mp_property_sub_delay(m_option_t * prop, int action, void *arg, - MPContext * mpctx) +static int mp_property_sub_delay(m_option_t *prop, int action, void *arg, + MPContext *mpctx) { if (!mpctx->sh_video) return M_PROPERTY_UNAVAILABLE; @@ -1703,8 +1734,8 @@ static int mp_property_sub_delay(m_option_t * prop, int action, void *arg, } /// Alignment of text subtitles (RW) -static int mp_property_sub_alignment(m_option_t * prop, int action, - void *arg, MPContext * mpctx) +static int mp_property_sub_alignment(m_option_t *prop, int action, + void *arg, MPContext *mpctx) { char *name[] = { MSGTR_Top, MSGTR_Center, MSGTR_Bottom }; @@ -1731,8 +1762,8 @@ static int mp_property_sub_alignment(m_option_t * prop, int action, } /// Subtitle visibility (RW) -static int mp_property_sub_visibility(m_option_t * prop, int action, - void *arg, MPContext * mpctx) +static int mp_property_sub_visibility(m_option_t *prop, int action, + void *arg, MPContext *mpctx) { if (!mpctx->sh_video) return M_PROPERTY_UNAVAILABLE; @@ -1753,8 +1784,8 @@ static int mp_property_sub_visibility(m_option_t * prop, int action, #ifdef CONFIG_ASS /// Use margins for libass subtitles (RW) -static int mp_property_ass_use_margins(m_option_t * prop, int action, - void *arg, MPContext * mpctx) +static int mp_property_ass_use_margins(m_option_t *prop, int action, + void *arg, MPContext *mpctx) { if (!mpctx->sh_video) return M_PROPERTY_UNAVAILABLE; @@ -1773,8 +1804,8 @@ static int mp_property_ass_use_margins(m_option_t * prop, int action, #endif /// Show only forced subtitles (RW) -static int mp_property_sub_forced_only(m_option_t * prop, int action, - void *arg, MPContext * mpctx) +static int mp_property_sub_forced_only(m_option_t *prop, int action, + void *arg, MPContext *mpctx) { if (!vo_spudec) return M_PROPERTY_UNAVAILABLE; @@ -1796,8 +1827,8 @@ static int mp_property_sub_forced_only(m_option_t * prop, int action, #ifdef CONFIG_FREETYPE /// Subtitle scale (RW) -static int mp_property_sub_scale(m_option_t * prop, int action, void *arg, - MPContext * mpctx) +static int mp_property_sub_scale(m_option_t *prop, int action, void *arg, + MPContext *mpctx) { switch (action) { @@ -1849,8 +1880,8 @@ static int mp_property_sub_scale(m_option_t * prop, int action, void *arg, #ifdef CONFIG_TV /// TV color settings (RW) -static int mp_property_tv_color(m_option_t * prop, int action, void *arg, - MPContext * mpctx) +static int mp_property_tv_color(m_option_t *prop, int action, void *arg, + MPContext *mpctx) { int r, val; tvi_handle_t *tvh = mpctx->demuxer->priv; @@ -1883,8 +1914,8 @@ static int mp_property_tv_color(m_option_t * prop, int action, void *arg, #endif #ifdef CONFIG_TV_TELETEXT -static int mp_property_teletext_common(m_option_t * prop, int action, void *arg, - MPContext * mpctx) +static int mp_property_teletext_common(m_option_t *prop, int action, void *arg, + MPContext *mpctx) { int val,result; int base_ioctl=(int)prop->priv; @@ -1924,8 +1955,8 @@ static int mp_property_teletext_common(m_option_t * prop, int action, void *arg, return result == TVI_CONTROL_TRUE ? M_PROPERTY_OK : M_PROPERTY_ERROR; } -static int mp_property_teletext_mode(m_option_t * prop, int action, void *arg, - MPContext * mpctx) +static int mp_property_teletext_mode(m_option_t *prop, int action, void *arg, + MPContext *mpctx) { tvi_handle_t *tvh = mpctx->demuxer->priv; int result; @@ -1937,14 +1968,14 @@ static int mp_property_teletext_mode(m_option_t * prop, int action, void *arg, return result; if(tvh->functions->control(tvh->priv, prop->priv, &val)==TVI_CONTROL_TRUE && val) - mp_input_set_section("teletext"); + mp_input_set_section(mpctx->input, "teletext"); else - mp_input_set_section("tv"); + mp_input_set_section(mpctx->input, "tv"); return M_PROPERTY_OK; } -static int mp_property_teletext_page(m_option_t * prop, int action, void *arg, - MPContext * mpctx) +static int mp_property_teletext_page(m_option_t *prop, int action, void *arg, + MPContext *mpctx) { tvi_handle_t *tvh = mpctx->demuxer->priv; int result; @@ -2047,15 +2078,15 @@ static const m_option_t mp_properties[] = { { "framedropping", mp_property_framedropping, CONF_TYPE_INT, M_OPT_RANGE, 0, 2, NULL }, { "gamma", mp_property_gamma, CONF_TYPE_INT, - M_OPT_RANGE, -100, 100, &vo_gamma_gamma }, + M_OPT_RANGE, -100, 100, (void *)offsetof(struct MPOpts, vo_gamma_gamma)}, { "brightness", mp_property_gamma, CONF_TYPE_INT, - M_OPT_RANGE, -100, 100, &vo_gamma_brightness }, + M_OPT_RANGE, -100, 100, (void *)offsetof(struct MPOpts, vo_gamma_brightness) }, { "contrast", mp_property_gamma, CONF_TYPE_INT, - M_OPT_RANGE, -100, 100, &vo_gamma_contrast }, + M_OPT_RANGE, -100, 100, (void *)offsetof(struct MPOpts, vo_gamma_contrast) }, { "saturation", mp_property_gamma, CONF_TYPE_INT, - M_OPT_RANGE, -100, 100, &vo_gamma_saturation }, + M_OPT_RANGE, -100, 100, (void *)offsetof(struct MPOpts, vo_gamma_saturation) }, { "hue", mp_property_gamma, CONF_TYPE_INT, - M_OPT_RANGE, -100, 100, &vo_gamma_hue }, + M_OPT_RANGE, -100, 100, (void *)offsetof(struct MPOpts, vo_gamma_hue) }, { "panscan", mp_property_panscan, CONF_TYPE_FLOAT, M_OPT_RANGE, 0, 1, NULL }, { "vsync", mp_property_vsync, CONF_TYPE_FLAG, @@ -2150,7 +2181,7 @@ char* mp_property_print(const char *name, void* ctx) return ret; } -char *property_expand_string(MPContext * mpctx, char *str) +char *property_expand_string(MPContext *mpctx, char *str) { return m_properties_expand_string(mp_properties, str, mpctx); } @@ -2203,6 +2234,7 @@ static struct { { "loop", MP_CMD_LOOP, 0, 0, -1, MSGTR_LoopStatus }, { "chapter", MP_CMD_SEEK_CHAPTER, 0, 0, -1, NULL }, { "angle", MP_CMD_SWITCH_ANGLE, 0, 0, -1, NULL }, + { "pause", MP_CMD_PAUSE, 0, 0, -1, NULL }, // audio { "volume", MP_CMD_VOLUME, 0, OSD_VOLUME, -1, MSGTR_Volume }, { "mute", MP_CMD_MUTE, 1, 0, -1, MSGTR_MuteStatus }, @@ -2250,7 +2282,7 @@ static struct { /// Handle commands that set a property. -static int set_property_command(MPContext * mpctx, mp_cmd_t * cmd) +static int set_property_command(MPContext *mpctx, mp_cmd_t *cmd) { int i, r; m_option_t* prop; @@ -2284,12 +2316,12 @@ static int set_property_command(MPContext * mpctx, mp_cmd_t * cmd) if (set_prop_cmd[i].osd_progbar) { if (prop->type == CONF_TYPE_INT) { if (mp_property_do(pname, M_PROPERTY_GET, &r, mpctx) > 0) - set_osd_bar(set_prop_cmd[i].osd_progbar, + set_osd_bar(mpctx, set_prop_cmd[i].osd_progbar, set_prop_cmd[i].osd_msg, prop->min, prop->max, r); } else if (prop->type == CONF_TYPE_FLOAT) { float f; if (mp_property_do(pname, M_PROPERTY_GET, &f, mpctx) > 0) - set_osd_bar(set_prop_cmd[i].osd_progbar, + set_osd_bar(mpctx, set_prop_cmd[i].osd_progbar, set_prop_cmd[i].osd_msg, prop->min, prop->max, f); } else mp_msg(MSGT_CPLAYER, MSGL_ERR, @@ -2339,11 +2371,11 @@ static const struct { }; #endif -int run_command(MPContext * mpctx, mp_cmd_t * cmd) +void run_command(MPContext *mpctx, mp_cmd_t *cmd) { + struct MPOpts *opts = &mpctx->opts; sh_audio_t * const sh_audio = mpctx->sh_audio; sh_video_t * const sh_video = mpctx->sh_video; - int brk_cmd = 0; if (!set_property_command(mpctx, cmd)) switch (cmd->id) { case MP_CMD_SEEK:{ @@ -2354,21 +2386,20 @@ int run_command(MPContext * mpctx, mp_cmd_t * cmd) v = cmd->args[0].v.f; abs = (cmd->nargs > 1) ? cmd->args[1].v.i : 0; if (abs == 2) { /* Absolute seek to a specific timestamp in seconds */ - abs_seek_pos = SEEK_ABSOLUTE; + mpctx->abs_seek_pos = SEEK_ABSOLUTE; if (sh_video) mpctx->osd_function = (v > sh_video->pts) ? OSD_FFW : OSD_REW; - rel_seek_secs = v; + mpctx->rel_seek_secs = v; } else if (abs) { /* Absolute seek by percentage */ - abs_seek_pos = SEEK_ABSOLUTE | SEEK_FACTOR; + mpctx->abs_seek_pos = SEEK_ABSOLUTE | SEEK_FACTOR; if (sh_video) mpctx->osd_function = OSD_FFW; // Direction isn't set correctly - rel_seek_secs = v / 100.0; + mpctx->rel_seek_secs = v / 100.0; } else { - rel_seek_secs += v; + mpctx->rel_seek_secs += v; mpctx->osd_function = (v > 0) ? OSD_FFW : OSD_REW; } - brk_cmd = 1; } break; @@ -2444,9 +2475,7 @@ int run_command(MPContext * mpctx, mp_cmd_t * cmd) case MP_CMD_EDL_MARK: if (edl_fd) { float v = sh_video ? sh_video->pts : - playing_audio_pts(sh_audio, mpctx->d_audio, - mpctx->audio_out); - + playing_audio_pts(mpctx); if (mpctx->begin_skip == MP_NOPTS_VALUE) { mpctx->begin_skip = v; mp_msg(MSGT_CPLAYER, MSGL_INFO, MSGTR_EdloutStartSkip); @@ -2466,40 +2495,38 @@ int run_command(MPContext * mpctx, mp_cmd_t * cmd) if (!sh_video) break; if (cmd->nargs == 0 || cmd->args[0].v.f == -1) - movie_aspect = (float) sh_video->disp_w / sh_video->disp_h; + opts->movie_aspect = (float) sh_video->disp_w / sh_video->disp_h; else - movie_aspect = cmd->args[0].v.f; + opts->movie_aspect = cmd->args[0].v.f; mpcodecs_config_vo(sh_video, sh_video->disp_w, sh_video->disp_h, 0); break; case MP_CMD_SPEED_INCR:{ float v = cmd->args[0].v.f; - playback_speed += v; - build_afilter_chain(sh_audio, &ao_data); + opts->playback_speed += v; + build_afilter_chain(mpctx, sh_audio, &ao_data); set_osd_msg(OSD_MSG_SPEED, 1, osd_duration, MSGTR_OSDSpeed, - playback_speed); + opts->playback_speed); } break; case MP_CMD_SPEED_MULT:{ float v = cmd->args[0].v.f; - playback_speed *= v; - build_afilter_chain(sh_audio, &ao_data); + opts->playback_speed *= v; + build_afilter_chain(mpctx, sh_audio, &ao_data); set_osd_msg(OSD_MSG_SPEED, 1, osd_duration, MSGTR_OSDSpeed, - playback_speed); + opts->playback_speed); } break; case MP_CMD_SPEED_SET:{ float v = cmd->args[0].v.f; - playback_speed = v; - build_afilter_chain(sh_audio, &ao_data); + opts->playback_speed = v; + build_afilter_chain(mpctx, sh_audio, &ao_data); set_osd_msg(OSD_MSG_SPEED, 1, osd_duration, MSGTR_OSDSpeed, - playback_speed); + opts->playback_speed); } break; case MP_CMD_FRAME_STEP: - case MP_CMD_PAUSE: - cmd->pausing = 1; - brk_cmd = 1; + add_step_frame(mpctx); break; case MP_CMD_FILE_FILTER: @@ -2507,7 +2534,7 @@ int run_command(MPContext * mpctx, mp_cmd_t * cmd) break; case MP_CMD_QUIT: - exit_player_with_rc(EXIT_QUIT, + exit_player_with_rc(mpctx, EXIT_QUIT, (cmd->nargs > 0) ? cmd->args[0].v.i : 0); case MP_CMD_PLAY_TREE_STEP:{ @@ -2531,14 +2558,13 @@ int run_command(MPContext * mpctx, mp_cmd_t * cmd) play_tree_iter_new_copy(mpctx->playtree_iter); if (play_tree_iter_step(i, n, 0) == PLAY_TREE_ITER_ENTRY) - mpctx->eof = + mpctx->stop_play = (n > 0) ? PT_NEXT_ENTRY : PT_PREV_ENTRY; play_tree_iter_free(i); } else - mpctx->eof = (n > 0) ? PT_NEXT_ENTRY : PT_PREV_ENTRY; - if (mpctx->eof) + mpctx->stop_play = (n > 0) ? PT_NEXT_ENTRY : PT_PREV_ENTRY; + if (mpctx->stop_play) mpctx->play_tree_step = n; - brk_cmd = 1; } } break; @@ -2551,11 +2577,10 @@ int run_command(MPContext * mpctx, mp_cmd_t * cmd) play_tree_iter_t *i = play_tree_iter_new_copy(mpctx->playtree_iter); if (play_tree_iter_up_step(i, n, 0) == PLAY_TREE_ITER_ENTRY) - mpctx->eof = (n > 0) ? PT_UP_NEXT : PT_UP_PREV; + mpctx->stop_play = (n > 0) ? PT_UP_NEXT : PT_UP_PREV; play_tree_iter_free(i); } else - mpctx->eof = (n > 0) ? PT_UP_NEXT : PT_UP_PREV; - brk_cmd = 1; + mpctx->stop_play = (n > 0) ? PT_UP_NEXT : PT_UP_PREV; } break; @@ -2565,11 +2590,10 @@ int run_command(MPContext * mpctx, mp_cmd_t * cmd) if (v > 0 && mpctx->playtree_iter->file < mpctx->playtree_iter->num_files) - mpctx->eof = PT_NEXT_SRC; + mpctx->stop_play = PT_NEXT_SRC; else if (v < 0 && mpctx->playtree_iter->file > 1) - mpctx->eof = PT_PREV_SRC; + mpctx->stop_play = PT_PREV_SRC; } - brk_cmd = 1; break; case MP_CMD_SUB_STEP: @@ -2589,7 +2613,7 @@ int run_command(MPContext * mpctx, mp_cmd_t * cmd) break; case MP_CMD_SUB_LOG: - log_sub(); + log_sub(mpctx); break; case MP_CMD_OSD:{ @@ -2650,14 +2674,13 @@ int run_command(MPContext * mpctx, mp_cmd_t * cmd) play_tree_free_list(mpctx->playtree->child, 1); play_tree_set_child(mpctx->playtree, e); pt_iter_goto_head(mpctx->playtree_iter); - mpctx->eof = PT_NEXT_SRC; + mpctx->stop_play = PT_NEXT_SRC; } - brk_cmd = 1; } break; case MP_CMD_LOADLIST:{ - play_tree_t *e = parse_playlist_file(cmd->args[0].v.s); + play_tree_t *e = parse_playlist_file(mpctx->mconfig, cmd->args[0].v.s); if (!e) mp_msg(MSGT_CPLAYER, MSGL_ERR, MSGTR_PlaylistLoadUnable, cmd->args[0].v.s); @@ -2673,10 +2696,9 @@ int run_command(MPContext * mpctx, mp_cmd_t * cmd) play_tree_free_list(mpctx->playtree->child, 1); play_tree_set_child(mpctx->playtree, e); pt_iter_goto_head(mpctx->playtree_iter); - mpctx->eof = PT_NEXT_SRC; + mpctx->stop_play = PT_NEXT_SRC; } } - brk_cmd = 1; } break; @@ -2685,8 +2707,7 @@ int run_command(MPContext * mpctx, mp_cmd_t * cmd) while (play_tree_iter_up_step (mpctx->playtree_iter, 0, 1) != PLAY_TREE_ITER_END) /* NOP */ ; - mpctx->eof = PT_STOP; - brk_cmd = 1; + mpctx->stop_play = PT_STOP; break; #ifdef CONFIG_RADIO @@ -2808,8 +2829,10 @@ int run_command(MPContext * mpctx, mp_cmd_t * cmd) dir = DVB_CHANNEL_LOWER; - if (dvb_step_channel(mpctx->stream, dir)) - mpctx->eof = mpctx->dvbin_reopen = 1; + if (dvb_step_channel(mpctx->stream, dir)) { + mpctx->stop_play = PT_NEXT_ENTRY; + mpctx->dvbin_reopen = 1; + } } #endif /* CONFIG_DVBIN */ break; @@ -2839,9 +2862,11 @@ int run_command(MPContext * mpctx, mp_cmd_t * cmd) if (mpctx->stream->type == STREAMTYPE_DVB) { mpctx->last_dvb_step = 1; - if (dvb_set_channel - (mpctx->stream, cmd->args[1].v.i, cmd->args[0].v.i)) - mpctx->eof = mpctx->dvbin_reopen = 1; + if (dvb_set_channel(mpctx->stream, cmd->args[1].v.i, + cmd->args[0].v.i)) { + mpctx->stop_play = PT_NEXT_ENTRY; + mpctx->dvbin_reopen = 1; + } } break; #endif /* CONFIG_DVBIN */ @@ -2895,7 +2920,7 @@ int run_command(MPContext * mpctx, mp_cmd_t * cmd) case MP_CMD_SUB_LOAD: if (sh_video) { int n = mpctx->set_of_sub_size; - add_subtitles(cmd->args[0].v.s, sh_video->fps, 0); + add_subtitles(mpctx, cmd->args[0].v.s, sh_video->fps, 0); if (n != mpctx->set_of_sub_size) { if (mpctx->global_sub_indices[SUB_SOURCE_SUBS] < 0) mpctx->global_sub_indices[SUB_SOURCE_SUBS] = @@ -2924,7 +2949,8 @@ int run_command(MPContext * mpctx, mp_cmd_t * cmd) if (mpctx->set_of_sub_pos >= 0) { mpctx->global_sub_pos = -2; subdata = NULL; - mp_input_queue_cmd(mp_input_parse_cmd("sub_select")); + mp_input_queue_cmd(mpctx->input, + mp_input_parse_cmd("sub_select")); } } else if (v < mpctx->set_of_sub_size) { subd = mpctx->set_of_subtitles[v]; @@ -2935,7 +2961,8 @@ int run_command(MPContext * mpctx, mp_cmd_t * cmd) if (mpctx->set_of_sub_pos == v) { mpctx->global_sub_pos = -2; subdata = NULL; - mp_input_queue_cmd(mp_input_parse_cmd("sub_select")); + mp_input_queue_cmd(mpctx->input, + mp_input_parse_cmd("sub_select")); } else if (mpctx->set_of_sub_pos > v) { --mpctx->set_of_sub_pos; --mpctx->global_sub_pos; @@ -2960,7 +2987,7 @@ int run_command(MPContext * mpctx, mp_cmd_t * cmd) break; case MP_CMD_SCREENSHOT: - if (vo_config_count) { + if (mpctx->video_out && mpctx->video_out->config_ok) { mp_msg(MSGT_CPLAYER, MSGL_INFO, "sending VFCTRL_SCREENSHOT!\n"); if (CONTROL_OK != ((vf_instance_t *) sh_video->vfilter)-> @@ -2984,12 +3011,12 @@ int run_command(MPContext * mpctx, mp_cmd_t * cmd) case MP_CMD_GET_FILENAME:{ mp_msg(MSGT_GLOBAL, MSGL_INFO, "ANS_FILENAME='%s'\n", - get_metadata(META_NAME)); + get_metadata(mpctx, META_NAME)); } break; case MP_CMD_GET_VIDEO_CODEC:{ - char *inf = get_metadata(META_VIDEO_CODEC); + char *inf = get_metadata(mpctx, META_VIDEO_CODEC); if (!inf) inf = strdup(""); mp_msg(MSGT_GLOBAL, MSGL_INFO, "ANS_VIDEO_CODEC='%s'\n", inf); @@ -2998,7 +3025,7 @@ int run_command(MPContext * mpctx, mp_cmd_t * cmd) break; case MP_CMD_GET_VIDEO_BITRATE:{ - char *inf = get_metadata(META_VIDEO_BITRATE); + char *inf = get_metadata(mpctx, META_VIDEO_BITRATE); if (!inf) inf = strdup(""); mp_msg(MSGT_GLOBAL, MSGL_INFO, "ANS_VIDEO_BITRATE='%s'\n", inf); @@ -3007,7 +3034,7 @@ int run_command(MPContext * mpctx, mp_cmd_t * cmd) break; case MP_CMD_GET_VIDEO_RESOLUTION:{ - char *inf = get_metadata(META_VIDEO_RESOLUTION); + char *inf = get_metadata(mpctx, META_VIDEO_RESOLUTION); if (!inf) inf = strdup(""); mp_msg(MSGT_GLOBAL, MSGL_INFO, @@ -3017,7 +3044,7 @@ int run_command(MPContext * mpctx, mp_cmd_t * cmd) break; case MP_CMD_GET_AUDIO_CODEC:{ - char *inf = get_metadata(META_AUDIO_CODEC); + char *inf = get_metadata(mpctx, META_AUDIO_CODEC); if (!inf) inf = strdup(""); mp_msg(MSGT_GLOBAL, MSGL_INFO, "ANS_AUDIO_CODEC='%s'\n", inf); @@ -3026,7 +3053,7 @@ int run_command(MPContext * mpctx, mp_cmd_t * cmd) break; case MP_CMD_GET_AUDIO_BITRATE:{ - char *inf = get_metadata(META_AUDIO_BITRATE); + char *inf = get_metadata(mpctx, META_AUDIO_BITRATE); if (!inf) inf = strdup(""); mp_msg(MSGT_GLOBAL, MSGL_INFO, "ANS_AUDIO_BITRATE='%s'\n", inf); @@ -3035,7 +3062,7 @@ int run_command(MPContext * mpctx, mp_cmd_t * cmd) break; case MP_CMD_GET_AUDIO_SAMPLES:{ - char *inf = get_metadata(META_AUDIO_SAMPLES); + char *inf = get_metadata(mpctx, META_AUDIO_SAMPLES); if (!inf) inf = strdup(""); mp_msg(MSGT_GLOBAL, MSGL_INFO, "ANS_AUDIO_SAMPLES='%s'\n", inf); @@ -3044,7 +3071,7 @@ int run_command(MPContext * mpctx, mp_cmd_t * cmd) break; case MP_CMD_GET_META_TITLE:{ - char *inf = get_metadata(META_INFO_TITLE); + char *inf = get_metadata(mpctx, META_INFO_TITLE); if (!inf) inf = strdup(""); mp_msg(MSGT_GLOBAL, MSGL_INFO, "ANS_META_TITLE='%s'\n", inf); @@ -3053,7 +3080,7 @@ int run_command(MPContext * mpctx, mp_cmd_t * cmd) break; case MP_CMD_GET_META_ARTIST:{ - char *inf = get_metadata(META_INFO_ARTIST); + char *inf = get_metadata(mpctx, META_INFO_ARTIST); if (!inf) inf = strdup(""); mp_msg(MSGT_GLOBAL, MSGL_INFO, "ANS_META_ARTIST='%s'\n", inf); @@ -3062,7 +3089,7 @@ int run_command(MPContext * mpctx, mp_cmd_t * cmd) break; case MP_CMD_GET_META_ALBUM:{ - char *inf = get_metadata(META_INFO_ALBUM); + char *inf = get_metadata(mpctx, META_INFO_ALBUM); if (!inf) inf = strdup(""); mp_msg(MSGT_GLOBAL, MSGL_INFO, "ANS_META_ALBUM='%s'\n", inf); @@ -3071,7 +3098,7 @@ int run_command(MPContext * mpctx, mp_cmd_t * cmd) break; case MP_CMD_GET_META_YEAR:{ - char *inf = get_metadata(META_INFO_YEAR); + char *inf = get_metadata(mpctx, META_INFO_YEAR); if (!inf) inf = strdup(""); mp_msg(MSGT_GLOBAL, MSGL_INFO, "ANS_META_YEAR='%s'\n", inf); @@ -3080,7 +3107,7 @@ int run_command(MPContext * mpctx, mp_cmd_t * cmd) break; case MP_CMD_GET_META_COMMENT:{ - char *inf = get_metadata(META_INFO_COMMENT); + char *inf = get_metadata(mpctx, META_INFO_COMMENT); if (!inf) inf = strdup(""); mp_msg(MSGT_GLOBAL, MSGL_INFO, "ANS_META_COMMENT='%s'\n", inf); @@ -3089,7 +3116,7 @@ int run_command(MPContext * mpctx, mp_cmd_t * cmd) break; case MP_CMD_GET_META_TRACK:{ - char *inf = get_metadata(META_INFO_TRACK); + char *inf = get_metadata(mpctx, META_INFO_TRACK); if (!inf) inf = strdup(""); mp_msg(MSGT_GLOBAL, MSGL_INFO, "ANS_META_TRACK='%s'\n", inf); @@ -3098,7 +3125,7 @@ int run_command(MPContext * mpctx, mp_cmd_t * cmd) break; case MP_CMD_GET_META_GENRE:{ - char *inf = get_metadata(META_INFO_GENRE); + char *inf = get_metadata(mpctx, META_INFO_GENRE); if (!inf) inf = strdup(""); mp_msg(MSGT_GLOBAL, MSGL_INFO, "ANS_META_GENRE='%s'\n", inf); @@ -3107,7 +3134,7 @@ int run_command(MPContext * mpctx, mp_cmd_t * cmd) break; case MP_CMD_GET_VO_FULLSCREEN: - if (mpctx->video_out && vo_config_count) + if (mpctx->video_out && mpctx->video_out->config_ok) mp_msg(MSGT_GLOBAL, MSGL_INFO, "ANS_VO_FULLSCREEN=%d\n", vo_fs); break; @@ -3121,9 +3148,7 @@ int run_command(MPContext * mpctx, mp_cmd_t * cmd) if (sh_video) pos = sh_video->pts; else if (sh_audio && mpctx->audio_out) - pos = - playing_audio_pts(sh_audio, mpctx->d_audio, - mpctx->audio_out); + pos = playing_audio_pts(mpctx); mp_msg(MSGT_GLOBAL, MSGL_INFO, "ANS_TIME_POSITION=%.1f\n", pos); } break; @@ -3138,7 +3163,7 @@ int run_command(MPContext * mpctx, mp_cmd_t * cmd) break; case MP_CMD_KEYDOWN_EVENTS: - mplayer_put_key(cmd->args[0].v.i); + mplayer_put_key(mpctx->key_fifo, cmd->args[0].v.i); break; case MP_CMD_SET_MOUSE_POS:{ @@ -3146,7 +3171,7 @@ int run_command(MPContext * mpctx, mp_cmd_t * cmd) double dx, dy; pointer_x = cmd->args[0].v.i; pointer_y = cmd->args[1].v.i; - rescale_input_coordinates(pointer_x, pointer_y, &dx, &dy); + rescale_input_coordinates(mpctx, pointer_x, pointer_y, &dx, &dy); #ifdef CONFIG_DVDNAV if (mpctx->stream->type == STREAMTYPE_DVDNAV && dx > 0.0 && dy > 0.0) { @@ -3207,18 +3232,13 @@ int run_command(MPContext * mpctx, mp_cmd_t * cmd) switch (cmd->pausing) { case 1: // "pausing" - mpctx->osd_function = OSD_PAUSE; + pause_player(mpctx); break; case 3: // "pausing_toggle" - mpctx->was_paused = !mpctx->was_paused; - if (mpctx->was_paused) - mpctx->osd_function = OSD_PAUSE; - else if (mpctx->osd_function == OSD_PAUSE) - mpctx->osd_function = OSD_PLAY; + if (mpctx->paused) + unpause_player(mpctx); + else + pause_player(mpctx); break; - case 2: // "pausing_keep" - if (mpctx->was_paused) - mpctx->osd_function = OSD_PAUSE; } - return brk_cmd; } @@ -4,7 +4,7 @@ struct MPContext; struct mp_cmd; -int run_command(struct MPContext *mpctx, struct mp_cmd *cmd); +void run_command(struct MPContext *mpctx, struct mp_cmd *cmd); char *property_expand_string(struct MPContext *mpctx, char *str); void property_print_help(void); diff --git a/common.mak b/common.mak index 4be056c876..82f88fdbee 100644 --- a/common.mak +++ b/common.mak @@ -19,28 +19,17 @@ endif ALLFFLIBS = avcodec avdevice avfilter avformat avutil postproc swscale CFLAGS := -DHAVE_AV_CONFIG_H -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE \ - -I$(BUILD_ROOT_REL) -I$(SRC_PATH) $(OPTFLAGS) + -I$(BUILD_ROOT_REL) -I$(SRC_PATH) -I$(SRC_PATH)/ffmpeg $(OPTFLAGS) %.o: %.c - $(CC) $(CFLAGS) $(LIBOBJFLAGS) -c -o $@ $< + $(CC) $(CFLAGS) $(LIBOBJFLAGS) -c -o $@ -MD -MP -MF $*.d $< %.o: %.S - $(CC) $(CFLAGS) $(LIBOBJFLAGS) -c -o $@ $< + $(CC) $(CFLAGS) $(LIBOBJFLAGS) -c -o $@ -MD -MP -MF $*.d $< %.ho: %.h $(CC) $(CFLAGS) $(LIBOBJFLAGS) -Wno-unused -c -o $@ -x c $< -%.d: %.c - $(DEPEND_CMD) > $@ - -%.d: %.S - $(DEPEND_CMD) > $@ - -%.d: %.cpp - $(DEPEND_CMD) > $@ - -%.o: %.d - %$(EXESUF): %.c SVN_ENTRIES = $(SRC_PATH_BARE)/.svn/entries @@ -93,9 +82,7 @@ $(SUBDIR)%-test.o: $(SUBDIR)%-test.c $(SUBDIR)x86/%.o: $(SUBDIR)x86/%.asm $(YASM) $(YASMFLAGS) -I $$(<D)/ -o $$@ $$< - -$(SUBDIR)x86/%.d: $(SUBDIR)x86/%.asm - $(YASM) $(YASMFLAGS) -I $$(<D)/ -M -o $$(@:%.d=%.o) $$< > $$@ + $(YASM) $(YASMFLAGS) -I $$(<D)/ -M -o $$@ $$< > $$(@:%.o=%.d) clean:: rm -f $(TESTS) $(addprefix $(SUBDIR),$(CLEANFILES) $(CLEANSUFFIXES) $(LIBSUFFIXES)) \ @@ -522,19 +522,19 @@ _libavutil_so=auto _libavcodec_a=auto _libamr_nb=auto _libamr_wb=auto -_libavdecoders_all=`sed -n 's/^[^#]*DEC.*(.*, *\(.*\)).*/\1_decoder/p' libavcodec/allcodecs.c | tr '[a-z]' '[A-Z]'` +_libavdecoders_all=`sed -n 's/^[^#]*DEC.*(.*, *\(.*\)).*/\1_decoder/p' ffmpeg/libavcodec/allcodecs.c | tr '[a-z]' '[A-Z]'` _libavdecoders=` echo $_libavdecoders_all | sed -e 's/ LIB[A-Z0-9_]*_DECODER//g' -e s/MPEG4AAC_DECODER// -e s/H264_VDPAU_DECODER// -e s/MPEG_VDPAU_DECODER// -e s/MPEG1_VDPAU_DECODER// -e s/VC1_VDPAU_DECODER// -e s/WMV3_VDPAU_DECODER// ` -_libavencoders_all=`sed -n 's/^[^#]*ENC.*(.*, *\(.*\)).*/\1_encoder/p' libavcodec/allcodecs.c | tr '[a-z]' '[A-Z]'` +_libavencoders_all=`sed -n 's/^[^#]*ENC.*(.*, *\(.*\)).*/\1_encoder/p' ffmpeg/libavcodec/allcodecs.c | tr '[a-z]' '[A-Z]'` _libavencoders=` echo $_libavencoders_all | sed 's/ LIB[A-Z0-9_]*_ENCODER//g'` -_libavparsers_all=`sed -n 's/^[^#]*PARSER.*(.*, *\(.*\)).*/\1_parser/p' libavcodec/allcodecs.c | tr '[a-z]' '[A-Z]'` +_libavparsers_all=`sed -n 's/^[^#]*PARSER.*(.*, *\(.*\)).*/\1_parser/p' ffmpeg/libavcodec/allcodecs.c | tr '[a-z]' '[A-Z]'` _libavparsers=$_libavparsers_all -_libavbsfs_all=`sed -n 's/^[^#]*BSF.*(.*, *\(.*\)).*/\1_bsf/p' libavcodec/allcodecs.c | tr '[a-z]' '[A-Z]'` +_libavbsfs_all=`sed -n 's/^[^#]*BSF.*(.*, *\(.*\)).*/\1_bsf/p' ffmpeg/libavcodec/allcodecs.c | tr '[a-z]' '[A-Z]'` _libavbsfs=$_libavbsfs_all -_libavdemuxers_all=`sed -n 's/^[^#]*DEMUX.*(.*, *\(.*\)).*/\1_demuxer/p' libavformat/allformats.c | tr '[a-z]' '[A-Z]'` +_libavdemuxers_all=`sed -n 's/^[^#]*DEMUX.*(.*, *\(.*\)).*/\1_demuxer/p' ffmpeg/libavformat/allformats.c | tr '[a-z]' '[A-Z]'` _libavdemuxers=`echo $_libavdemuxers_all | sed -e 's/ LIB[A-Z0-9_]*_DEMUXER//g' -e s/REDIR_DEMUXER// -e s/RTSP_DEMUXER// -e s/SDP_DEMUXER// -e s/AVISYNTH_DEMUXER// ` -_libavmuxers_all=`sed -n 's/^[^#]*_MUX.*(.*, *\(.*\)).*/\1_muxer/p' libavformat/allformats.c | tr '[a-z]' '[A-Z]'` +_libavmuxers_all=`sed -n 's/^[^#]*_MUX.*(.*, *\(.*\)).*/\1_muxer/p' ffmpeg/libavformat/allformats.c | tr '[a-z]' '[A-Z]'` _libavmuxers=`echo $_libavmuxers_all | sed -e 's/ LIB[A-Z0-9_]*_MUXER//g' -e s/RTP_MUXER// ` -_libavprotocols_all=`sed -n 's/^[^#]*PROTOCOL.*(.*, *\(.*\)).*/\1_protocol/p' libavformat/allformats.c | tr '[a-z]' '[A-Z]'` +_libavprotocols_all=`sed -n 's/^[^#]*PROTOCOL.*(.*, *\(.*\)).*/\1_protocol/p' ffmpeg/libavformat/allformats.c | tr '[a-z]' '[A-Z]'` _libavcodec_so=auto _libavformat_a=auto _libavformat_so=auto @@ -1289,6 +1289,11 @@ for ac_option do esac done +if test "$_gui" = yes ; then + echo "Error: --enable-gui is no longer supported. Use an external frontend if you want a GUI." >&2 + exit 1 +fi + # Atmos: moved this here, to be correct, if --prefix is specified test -z "$_bindir" && _bindir="$_prefix/bin" test -z "$_datadir" && _datadir="$_prefix/share/mplayer" @@ -2176,6 +2181,7 @@ EOF _arch='ALPHA' _target_arch='ARCH_ALPHA = yes' iproc='alpha' + def_fast_64bit='#define HAVE_FAST_64BIT 1' echocheck "CPU type" cat > $TMPC << EOF @@ -5655,6 +5661,9 @@ echores "$_vcd" echocheck "dvdread" +if test "$_dvdread_internal" = auto && test ! -f "libdvdread4/dvd_reader.c" ; then + _dvdread_internal=no +fi if test "$_dvdread_internal" = auto ; then _dvdread_internal=no _dvdread=no @@ -6679,7 +6688,7 @@ echores "$_live" echocheck "FFmpeg libavutil" if test "$_libavutil_a" = auto ; then - if test -d libavutil ; then + if test -d ffmpeg/libavutil ; then _libavutil_a=yes _res_comment="static" else @@ -6719,7 +6728,7 @@ echores "$_libavutil" echocheck "FFmpeg libavcodec" if test "$_libavcodec_a" = auto ; then _libavcodec_a=no - if test -d libavcodec && test -f libavcodec/utils.c ; then + if test -d ffmpeg/libavcodec && test -f ffmpeg/libavcodec/utils.c ; then _libavcodec_a="yes" _res_comment="static" fi @@ -6763,7 +6772,7 @@ echores "$_libavcodec" echocheck "FFmpeg libavformat" if test "$_libavformat_a" = auto ; then _libavformat_a=no - if test -d libavformat && test -f libavformat/utils.c ; then + if test -d ffmpeg/libavformat && test -f ffmpeg/libavformat/utils.c ; then _libavformat_a=yes _res_comment="static" fi @@ -6799,7 +6808,7 @@ echores "$_libavformat" echocheck "FFmpeg libpostproc" if test "$_libpostproc_a" = auto ; then _libpostproc_a=no - if test -d libpostproc && test -f libpostproc/postprocess.h ; then + if test -d ffmpeg/libpostproc && test -f ffmpeg/libpostproc/postprocess.h ; then _libpostproc_a='yes' _res_comment="static" fi @@ -6981,7 +6990,7 @@ if test "$_x264" = auto ; then cat > $TMPC << EOF #include <inttypes.h> #include <x264.h> -#if X264_BUILD < 59 +#if X264_BUILD < 65 #error We do not support old versions of x264. Get the latest from SVN. #endif int main(void) { x264_encoder_open((void*)0); return 0; } @@ -7843,6 +7852,9 @@ fi #because libdvdnavmini is intentionally not linked against libdvdread (to permit mplayer # to use its own copy of the library) echocheck "DVD support (libdvdnav)" +if test "$_dvdread_internal" = yes && test ! -f "libdvdnav/dvdnav.c" ; then + _dvdnav=no +fi dvdnav_internal=no if test "$_dvdnav" = auto ; then if test "$_dvdread_internal" = yes ; then @@ -7930,14 +7942,13 @@ if test "$_largefiles" = yes || freebsd ; then fi fi -CXXFLAGS=" $CFLAGS -D__STDC_LIMIT_MACROS" +CXXFLAGS=" $CFLAGS -Iffmpeg -D__STDC_LIMIT_MACROS" cat > $TMPC << EOF int main(void) { return 0; } EOF if test "$cc_vendor" = "gnu" ; then cc_check -std=gnu99 && CFLAGS="-std=gnu99 $CFLAGS" - cc_check -Wdeclaration-after-statement && CFLAGS="-Wdeclaration-after-statement $CFLAGS" cc_check -Wno-pointer-sign && CFLAGS="-Wno-pointer-sign $CFLAGS" cc_check -Wdisabled-optimization && CFLAGS="-Wdisabled-optimization $CFLAGS" cc_check -Wundef && CFLAGS="-Wundef $CFLAGS" @@ -7945,6 +7956,9 @@ else CFLAGS="-D_ISOC99_SOURCE -D_BSD_SOURCE $CFLAGS" fi +CFLAGS_FFMPEG="-I../.. $CFLAGS" +CFLAGS="-Iffmpeg $CFLAGS" + cc_check -mno-omit-leaf-frame-pointer && cflags_no_omit_leaf_frame_pointer="-mno-omit-leaf-frame-pointer" ############################################################################# @@ -7984,6 +7998,7 @@ EXTRA_INC = $_inc_extra EXTRAXX_INC = $_inc_extra $_inc_extraxx CFLAGS = $CFLAGS \$(EXTRA_INC) OPTFLAGS = $CFLAGS \$(EXTRA_INC) +FFMPEG_OFLAGS = $CFLAGS_FFMPEG \$(EXTRA_INC) CXXFLAGS = $CXXFLAGS \$(EXTRAXX_INC) CFLAGS_DHAHELPER = $cflags_dhahelper CFLAGS_FAAD_FIXED = $cflags_faad_fixed @@ -8713,6 +8728,9 @@ EOF # Do not overwrite an unchanged config.h to avoid superfluous rebuilds. cmp -s "$TMPH" config.h || mv -f "$TMPH" config.h +cp -p config.h ffmpeg/config.h +sed -e 's/OPTFLAGS/MPLAYER_OPTFLAGS/' -e 's/FFMPEG_OFLAGS/OPTFLAGS/' config.mak >ffmpeg/config.mak + ############################################################################# cat << EOF diff --git a/defaultopts.c b/defaultopts.c new file mode 100644 index 0000000000..5c9f9effcf --- /dev/null +++ b/defaultopts.c @@ -0,0 +1,57 @@ +#include <stddef.h> + +#include "config.h" +#include "defaultopts.h" +#include "options.h" + +void set_default_mplayer_options(struct MPOpts *opts) +{ + *opts = (const struct MPOpts){ + .audio_driver_list = NULL, + .video_driver_list = NULL, + .fixed_vo = 0, + .monitor_pixel_aspect = 1.0, + .vo_panscanrange = 1.0, + .vo_gamma_gamma = 1000, + .vo_gamma_brightness = 1000, + .vo_gamma_contrast = 1000, + .vo_gamma_saturation = 1000, + .vo_gamma_hue = 1000, + .loop_times = -1, + .user_correct_pts = -1, + .key_fifo_size = 7, + .doubleclick_time = 300, + .audio_id = -1, + .video_id = -1, + .sub_id = -2, + .playback_speed = 1., + .movie_aspect = -1., + .flip = -1, + .vd_use_slices = 1, + .lavc_param = (struct lavc_param){ + .workaround_bugs = 1, // autodetect + .error_resilience = 2, + .error_concealment = 3, + .threads = 1, + }, + .input = (struct input_conf){ + .config_file = "input.conf", + .ar_delay = 100, + .ar_rate = 8, + .use_joystick = 1, + .use_lirc = 1, + .use_lircc = 1, +#ifdef HAVE_APPLE_REMOTE + .use_ar = 1, +#else + .use_ar = 0, +#endif + } + }; +} + +void set_default_mencoder_options(struct MPOpts *opts) +{ + set_default_mplayer_options(opts); + opts->user_correct_pts = 0; +} diff --git a/defaultopts.h b/defaultopts.h new file mode 100644 index 0000000000..15067204a7 --- /dev/null +++ b/defaultopts.h @@ -0,0 +1,3 @@ +struct MPOpts; +void set_default_mplayer_options(struct MPOpts *opts); +void set_default_mencoder_options(struct MPOpts *opts); diff --git a/help/help_mp-en.h b/help/help_mp-en.h index aa78b641eb..246731ad2c 100644 --- a/help/help_mp-en.h +++ b/help/help_mp-en.h @@ -1152,7 +1152,6 @@ static char help_text[]= // ======================= audio output drivers ======================== // audio_out.c -#define MSGTR_AO_ALSA9_1x_Removed "audio_out: alsa9 and alsa1x modules were removed, use -ao alsa instead.\n" #define MSGTR_AO_TryingPreferredAudioDriver "Trying preferred audio driver '%.*s', options '%s'\n" #define MSGTR_AO_NoSuchDriver "No such audio driver '%.*s'\n" #define MSGTR_AO_FailedInit "Failed to initialize audio driver '%s'\n" diff --git a/input/appleir.c b/input/appleir.c index 2593f7cb5d..756c66047d 100644 --- a/input/appleir.c +++ b/input/appleir.c @@ -121,7 +121,7 @@ int mp_input_appleir_init (char *dev) return -1; } -int mp_input_appleir_read (int fd) +int mp_input_appleir_read(void *ctx, int fd) { struct input_event ev; int i, r; diff --git a/input/ar.c b/input/ar.c index 61a6de0c6d..41e7736e45 100644 --- a/input/ar.c +++ b/input/ar.c @@ -321,7 +321,7 @@ int is_mplayer_front() return 0; } -int mp_input_ar_read(int fd) +int mp_input_ar_read(void *ctx, int fd) { int i, down = 0; int ret = MP_INPUT_NOTHING; @@ -445,7 +445,7 @@ int main(void) } while (1) { - switch ((ret = mp_input_ar_read(0)) & ~MP_KEY_DOWN) { + switch ((ret = mp_input_ar_read(NULL, 0)) & ~MP_KEY_DOWN) { case AR_PLAY: printf(" - AR_PLAY."); break; case AR_PLAY_HOLD: printf(" - AR_PLAY_HOLD."); break; case AR_NEXT: printf(" - AR_NEXT."); break; diff --git a/input/ar.h b/input/ar.h index 31bbd0ade9..12944f84e1 100644 --- a/input/ar.h +++ b/input/ar.h @@ -37,11 +37,11 @@ /* MacOSX Driver */ int mp_input_ar_init(void); -int mp_input_ar_read(int fd); +int mp_input_ar_read(void *ctx, int fd); void mp_input_ar_close(int fd); /* Linux Driver */ int mp_input_appleir_init(char* dev); -int mp_input_appleir_read(int fd); +int mp_input_appleir_read(void *ctx, int fd); #endif /* MPLAYER_AR_H */ diff --git a/input/input.c b/input/input.c index dcbeb2b11d..1f1d4a6ebf 100644 --- a/input/input.c +++ b/input/input.c @@ -35,7 +35,6 @@ #include <assert.h> #endif #include "mp_fifo.h" -#include "osdep/getch2.h" #include "osdep/keycodes.h" #include "osdep/timer.h" #include "libavutil/avstring.h" @@ -44,6 +43,8 @@ #include "m_config.h" #include "m_option.h" #include "get_path.h" +#include "talloc.h" +#include "options.h" #include "joystick.h" @@ -57,6 +58,16 @@ #include "ar.h" +typedef struct mp_cmd_bind { + int input[MP_MAX_KEY_DOWN+1]; + char* cmd; +} mp_cmd_bind_t; + +typedef struct mp_key_name { + int key; + char* name; +} mp_key_name_t; + /// This array defines all known commands. /// The first field is an id used to recognize the command without too many strcmp. /// The second is obviously the command name. @@ -525,40 +536,71 @@ static const mp_cmd_bind_t gui_def_cmd_binds[] = { typedef struct mp_input_fd { int fd; - void* read_func; + union { + mp_key_func_t key; + mp_cmd_func_t cmd; + } read_func; mp_close_func_t close_func; + void *ctx; unsigned eof : 1; unsigned drop : 1; unsigned dead : 1; unsigned got_cmd : 1; unsigned no_select : 1; - unsigned no_readfunc_retval : 1; // These fields are for the cmd fds. char* buffer; int pos,size; } mp_input_fd_t; -typedef struct mp_cmd_filter_st mp_cmd_filter_t; +typedef struct mp_cmd_filter mp_cmd_filter_t; -struct mp_cmd_filter_st { +struct mp_cmd_filter { mp_input_cmd_filter filter; void* ctx; mp_cmd_filter_t* next; }; -typedef struct mp_cmd_bind_section_st mp_cmd_bind_section_t; +typedef struct mp_cmd_bind_section mp_cmd_bind_section_t; -struct mp_cmd_bind_section_st { +struct mp_cmd_bind_section { mp_cmd_bind_t* cmd_binds; char* section; mp_cmd_bind_section_t* next; }; -// These are the user defined binds -static mp_cmd_bind_section_t* cmd_binds_section = NULL; -static char* section = NULL; -static mp_cmd_bind_t* cmd_binds = NULL; -static mp_cmd_bind_t* cmd_binds_default = NULL; +struct input_ctx { + // Autorepeat stuff + short ar_state; + mp_cmd_t *ar_cmd; + unsigned int last_ar; + // Autorepeat config + unsigned int ar_delay; + unsigned int ar_rate; + + // these are the keys currently down + int key_down[MP_MAX_KEY_DOWN]; + unsigned int num_key_down; + unsigned int last_key_down; + + // List of command binding sections + mp_cmd_bind_section_t *cmd_bind_sections; + // Name of currently used command section + char *section; + // The command binds of current section + mp_cmd_bind_t *cmd_binds; + mp_cmd_bind_t *cmd_binds_default; + + mp_input_fd_t key_fds[MP_MAX_KEY_FD]; + unsigned int num_key_fd; + + mp_input_fd_t cmd_fds[MP_MAX_CMD_FD]; + unsigned int num_cmd_fd; + + mp_cmd_t *cmd_queue[CMD_QUEUE_SIZE]; + unsigned int cmd_queue_length, cmd_queue_start, cmd_queue_end; +}; + + static mp_cmd_filter_t* cmd_filters = NULL; // Callback to allow the menu filter to grab the incoming keys @@ -566,77 +608,44 @@ int (*mp_input_key_cb)(int code) = NULL; int async_quit_request; -static mp_input_fd_t key_fds[MP_MAX_KEY_FD]; -static unsigned int num_key_fd = 0; -static mp_input_fd_t cmd_fds[MP_MAX_CMD_FD]; -static unsigned int num_cmd_fd = 0; -static mp_cmd_t* cmd_queue[CMD_QUEUE_SIZE]; -static unsigned int cmd_queue_length = 0,cmd_queue_start = 0, cmd_queue_end = 0; - -// this is the key currently down -static int key_down[MP_MAX_KEY_DOWN]; -static unsigned int num_key_down = 0, last_key_down = 0; - -// Autorepeat stuff -static short ar_state = -1; -static mp_cmd_t* ar_cmd = NULL; -static unsigned int ar_delay = 100, ar_rate = 8, last_ar = 0; - -static int use_joystick = 1, use_lirc = 1, use_lircc = 1; -static char* config_file = "input.conf"; - -/* Apple Remote */ -#ifdef CONFIG_APPLE_REMOTE -static int use_ar = 1; -#else -static int use_ar = 0; -#endif - -static char* js_dev = NULL; -static char* ar_dev = NULL; - -static char* in_file = NULL; -static int in_file_fd = -1; - -static int mp_input_print_key_list(m_option_t* cfg); -static int mp_input_print_cmd_list(m_option_t* cfg); +static int print_key_list(m_option_t* cfg); +static int print_cmd_list(m_option_t* cfg); // Our command line options -static m_option_t input_conf[] = { - { "conf", &config_file, CONF_TYPE_STRING, CONF_GLOBAL, 0, 0, NULL }, - { "ar-dev", &ar_dev, CONF_TYPE_STRING, CONF_GLOBAL, 0, 0, NULL }, - { "ar-delay", &ar_delay, CONF_TYPE_INT, CONF_GLOBAL, 0, 0, NULL }, - { "ar-rate", &ar_rate, CONF_TYPE_INT, CONF_GLOBAL, 0, 0, NULL }, - { "keylist", mp_input_print_key_list, CONF_TYPE_FUNC, CONF_GLOBAL, 0, 0, NULL }, - { "cmdlist", mp_input_print_cmd_list, CONF_TYPE_FUNC, CONF_GLOBAL, 0, 0, NULL }, - { "js-dev", &js_dev, CONF_TYPE_STRING, CONF_GLOBAL, 0, 0, NULL }, - { "file", &in_file, CONF_TYPE_STRING, CONF_GLOBAL, 0, 0, NULL }, +static const m_option_t input_conf[] = { + OPT_STRING("conf", input.config_file, CONF_GLOBAL), + OPT_INT("ar-delay",input.ar_delay, CONF_GLOBAL), + OPT_INT("ar-rate", input.ar_rate, CONF_GLOBAL), + { "keylist", print_key_list, CONF_TYPE_FUNC, CONF_GLOBAL, 0, 0, NULL }, + { "cmdlist", print_cmd_list, CONF_TYPE_FUNC, CONF_GLOBAL, 0, 0, NULL }, + OPT_STRING("js-dev", input.js_dev, CONF_GLOBAL), + OPT_STRING("ar-dev", input.ar_dev, CONF_GLOBAL), + OPT_STRING("file", input.in_file, CONF_GLOBAL), { NULL, NULL, 0, 0, 0, 0, NULL} }; -static m_option_t mp_input_opts[] = { +static const m_option_t mp_input_opts[] = { { "input", &input_conf, CONF_TYPE_SUBCONFIG, 0, 0, 0, NULL}, - { "nojoystick", &use_joystick, CONF_TYPE_FLAG, CONF_GLOBAL, 1, 0, NULL }, - { "joystick", &use_joystick, CONF_TYPE_FLAG, CONF_GLOBAL, 0, 1, NULL }, - { "nolirc", &use_lirc, CONF_TYPE_FLAG, CONF_GLOBAL, 1, 0, NULL }, - { "lirc", &use_lirc, CONF_TYPE_FLAG, CONF_GLOBAL, 0, 1, NULL }, - { "nolircc", &use_lircc, CONF_TYPE_FLAG, CONF_GLOBAL, 1, 0, NULL }, - { "lircc", &use_lircc, CONF_TYPE_FLAG, CONF_GLOBAL, 0, 1, NULL }, - { "noar", &use_ar, CONF_TYPE_FLAG, CONF_GLOBAL, 1, 0, NULL }, - { "ar", &use_ar, CONF_TYPE_FLAG, CONF_GLOBAL, 0, 1, NULL }, + OPT_FLAG_OFF("nojoystick", input.use_joystick, CONF_GLOBAL), + OPT_FLAG_ON("joystick", input.use_joystick, CONF_GLOBAL), + OPT_FLAG_OFF("nolirc", input.use_lirc, CONF_GLOBAL), + OPT_FLAG_ON("lirc", input.use_lirc, CONF_GLOBAL), + OPT_FLAG_OFF("nolircc", input.use_lircc, CONF_GLOBAL), + OPT_FLAG_ON("lircc", input.use_lircc, CONF_GLOBAL), + OPT_FLAG_OFF("noar", input.use_ar, CONF_GLOBAL), + OPT_FLAG_ON("ar", input.use_ar, CONF_GLOBAL), { NULL, NULL, 0, 0, 0, 0, NULL} }; -static int -mp_input_default_cmd_func(int fd,char* buf, int l); +static int default_cmd_func(int fd,char* buf, int l); -static char* -mp_input_get_key_name(int key); +static char *get_key_name(int key, char buffer[12]); -int -mp_input_add_cmd_fd(int fd, int select, mp_cmd_func_t read_func, mp_close_func_t close_func) { - if(num_cmd_fd == MP_MAX_CMD_FD) { +int mp_input_add_cmd_fd(struct input_ctx *ictx, int fd, int select, + mp_cmd_func_t read_func, mp_close_func_t close_func) +{ + if (ictx->num_cmd_fd == MP_MAX_CMD_FD) { mp_msg(MSGT_INPUT,MSGL_ERR,MSGTR_INPUT_INPUT_ErrCantRegister2ManyCmdFds,fd); return 0; } @@ -645,57 +654,64 @@ mp_input_add_cmd_fd(int fd, int select, mp_cmd_func_t read_func, mp_close_func_t return 0; } - memset(&cmd_fds[num_cmd_fd],0,sizeof(mp_input_fd_t)); - cmd_fds[num_cmd_fd].fd = fd; - cmd_fds[num_cmd_fd].read_func = read_func ? read_func : mp_input_default_cmd_func; - cmd_fds[num_cmd_fd].close_func = close_func; - cmd_fds[num_cmd_fd].no_select = !select; - num_cmd_fd++; + ictx->cmd_fds[ictx->num_cmd_fd] = (struct mp_input_fd){ + .fd = fd, + .read_func.cmd = read_func ? read_func : default_cmd_func, + .close_func = close_func, + .no_select = !select + }; + ictx->num_cmd_fd++; return 1; } -void -mp_input_rm_cmd_fd(int fd) { +void mp_input_rm_cmd_fd(struct input_ctx *ictx, int fd) +{ + struct mp_input_fd *cmd_fds = ictx->cmd_fds; unsigned int i; - for(i = 0; i < num_cmd_fd; i++) { + for (i = 0; i < ictx->num_cmd_fd; i++) { if(cmd_fds[i].fd == fd) break; } - if(i == num_cmd_fd) + if (i == ictx->num_cmd_fd) return; if(cmd_fds[i].close_func) cmd_fds[i].close_func(cmd_fds[i].fd); if(cmd_fds[i].buffer) - free(cmd_fds[i].buffer); + talloc_free(cmd_fds[i].buffer); - if(i + 1 < num_cmd_fd) - memmove(&cmd_fds[i],&cmd_fds[i+1],(num_cmd_fd - i - 1)*sizeof(mp_input_fd_t)); - num_cmd_fd--; + if (i + 1 < ictx->num_cmd_fd) + memmove(&cmd_fds[i], &cmd_fds[i+1], + (ictx->num_cmd_fd - i - 1) * sizeof(mp_input_fd_t)); + ictx->num_cmd_fd--; } -void -mp_input_rm_key_fd(int fd) { +void mp_input_rm_key_fd(struct input_ctx *ictx, int fd) +{ + struct mp_input_fd *key_fds = ictx->key_fds; unsigned int i; - for(i = 0; i < num_key_fd; i++) { + for (i = 0; i < ictx->num_key_fd; i++) { if(key_fds[i].fd == fd) break; } - if(i == num_key_fd) + if (i == ictx->num_key_fd) return; if(key_fds[i].close_func) key_fds[i].close_func(key_fds[i].fd); - if(i + 1 < num_key_fd) - memmove(&key_fds[i],&key_fds[i+1],(num_key_fd - i - 1)*sizeof(mp_input_fd_t)); - num_key_fd--; + if(i + 1 < ictx->num_key_fd) + memmove(&key_fds[i], &key_fds[i+1], + (ictx->num_key_fd - i - 1) * sizeof(mp_input_fd_t)); + ictx->num_key_fd--; } -int -mp_input_add_key_fd(int fd, int select, mp_key_func_t read_func, mp_close_func_t close_func) { - if(num_key_fd == MP_MAX_KEY_FD) { +int mp_input_add_key_fd(struct input_ctx *ictx, int fd, int select, + mp_key_func_t read_func, mp_close_func_t close_func, + void *ctx) +{ + if (ictx->num_key_fd == MP_MAX_KEY_FD) { mp_msg(MSGT_INPUT,MSGL_ERR,MSGTR_INPUT_INPUT_ErrCantRegister2ManyKeyFds,fd); return 0; } @@ -704,44 +720,20 @@ mp_input_add_key_fd(int fd, int select, mp_key_func_t read_func, mp_close_func_t return 0; } - memset(&key_fds[num_key_fd],0,sizeof(mp_input_fd_t)); - key_fds[num_key_fd].fd = fd; - key_fds[num_key_fd].read_func = read_func; - key_fds[num_key_fd].close_func = close_func; - key_fds[num_key_fd].no_select = !select; - num_key_fd++; - - return 1; -} - -int -mp_input_add_event_fd(int fd, void (*read_func)(void)) -{ - if(num_key_fd == MP_MAX_KEY_FD) { - mp_msg(MSGT_INPUT,MSGL_ERR,MSGTR_INPUT_INPUT_ErrCantRegister2ManyKeyFds,fd); - return 0; - } - if (fd < 0) { - mp_msg(MSGT_INPUT, MSGL_ERR, "Invalid fd %i in mp_input_add_event_fd", fd); - return 0; - } - - memset(&key_fds[num_key_fd],0,sizeof(mp_input_fd_t)); - key_fds[num_key_fd].fd = fd; - key_fds[num_key_fd].read_func = read_func; - key_fds[num_key_fd].close_func = NULL; - key_fds[num_key_fd].no_readfunc_retval = 1; - num_key_fd++; + ictx->key_fds[ictx->num_key_fd] = (struct mp_input_fd){ + .fd = fd, + .read_func.key = read_func, + .close_func = close_func, + .no_select = !select, + .ctx = ctx, + }; + ictx->num_key_fd++; return 1; } -void mp_input_rm_event_fd(int fd) +int mp_input_parse_and_queue_cmds(struct input_ctx *ictx, const char *str) { - mp_input_rm_key_fd(fd); -} - -int mp_input_parse_and_queue_cmds(const char *str) { int cmd_num = 0; while (*str == '\n' || *str == '\r' || *str == ' ') @@ -749,17 +741,17 @@ int mp_input_parse_and_queue_cmds(const char *str) { while (*str) { mp_cmd_t *cmd; size_t len = strcspn(str, "\r\n"); - char *cmdbuf = malloc(len+1); + char *cmdbuf = talloc_size(NULL, len+1); av_strlcpy(cmdbuf, str, len+1); cmd = mp_input_parse_cmd(cmdbuf); if (cmd) { - mp_input_queue_cmd(cmd); + mp_input_queue_cmd(ictx, cmd); ++cmd_num; } str += len; while (*str == '\n' || *str == '\r' || *str == ' ') ++str; - free(cmdbuf); + talloc_free(cmdbuf); } return cmd_num; } @@ -769,7 +761,6 @@ mp_input_parse_cmd(char* str) { int i,l; int pausing = 0; char *ptr,*e; - mp_cmd_t *cmd; const mp_cmd_t *cmd_def; #ifdef MP_DEBUG @@ -814,10 +805,12 @@ mp_input_parse_cmd(char* str) { cmd_def = &mp_cmds[i]; - cmd = calloc(1, sizeof(mp_cmd_t)); - cmd->id = cmd_def->id; - cmd->name = strdup(cmd_def->name); - cmd->pausing = pausing; + mp_cmd_t *cmd = talloc_ptrtype(NULL, cmd); + *cmd = (mp_cmd_t){ + .id = cmd_def->id, + .name = talloc_strdup(cmd, cmd_def->name), + .pausing = pausing, + }; ptr = str; @@ -873,9 +866,7 @@ mp_input_parse_cmd(char* str) { ptr2 = e + 1; l--; } - cmd->args[i].v.s = malloc(l+1); - strncpy(cmd->args[i].v.s,start,l); - cmd->args[i].v.s[l] = '\0'; + cmd->args[i].v.s = talloc_strndup(cmd, start, l); if(term != ' ') ptr += l+2; } break; case -1: @@ -897,7 +888,7 @@ mp_input_parse_cmd(char* str) { for( ; i < MP_CMD_MAX_ARGS && cmd_def->args[i].type != -1 ; i++) { memcpy(&cmd->args[i],&cmd_def->args[i],sizeof(mp_cmd_arg_t)); if(cmd_def->args[i].type == MP_CMD_ARG_STRING && cmd_def->args[i].v.s != NULL) - cmd->args[i].v.s = strdup(cmd_def->args[i].v.s); + cmd->args[i].v.s = talloc_strdup(cmd, cmd_def->args[i].v.s); } if(i < MP_CMD_MAX_ARGS) @@ -908,21 +899,22 @@ mp_input_parse_cmd(char* str) { #define MP_CMD_MAX_SIZE 256 -static int -mp_input_read_cmd(mp_input_fd_t* mp_fd, char** ret) { +static int read_cmd(mp_input_fd_t* mp_fd, char** ret) +{ char* end; (*ret) = NULL; // Allocate the buffer if it doesn't exist if(!mp_fd->buffer) { - mp_fd->buffer = malloc(MP_CMD_MAX_SIZE); + mp_fd->buffer = talloc_size(NULL, MP_CMD_MAX_SIZE); mp_fd->pos = 0; mp_fd->size = MP_CMD_MAX_SIZE; } // Get some data if needed/possible while (!mp_fd->got_cmd && !mp_fd->eof && (mp_fd->size - mp_fd->pos > 1) ) { - int r = ((mp_cmd_func_t)mp_fd->read_func)(mp_fd->fd,mp_fd->buffer+mp_fd->pos,mp_fd->size - 1 - mp_fd->pos); + int r = mp_fd->read_func.cmd(mp_fd->fd, mp_fd->buffer+mp_fd->pos, + mp_fd->size - 1 - mp_fd->pos); // Error ? if(r < 0) { switch(r) { @@ -969,16 +961,12 @@ mp_input_read_cmd(mp_input_fd_t* mp_fd, char** ret) { l = end - mp_fd->buffer; // Not dropping : put the cmd in ret - if (!mp_fd->drop) { - (*ret) = malloc(l+1); - strncpy((*ret),mp_fd->buffer,l); - (*ret)[l] = '\0'; - } else { // Remove the dropping flag + if (!mp_fd->drop) + *ret = talloc_strndup(NULL, mp_fd->buffer, l); + else mp_fd->drop = 0; - } - if( mp_fd->pos - (l+1) > 0) - memmove(mp_fd->buffer,end+1,mp_fd->pos-(l+1)); mp_fd->pos -= l+1; + memmove(mp_fd->buffer, end+1, mp_fd->pos); } if(*ret) @@ -987,9 +975,8 @@ mp_input_read_cmd(mp_input_fd_t* mp_fd, char** ret) { return MP_INPUT_NOTHING; } -static int -mp_input_default_cmd_func(int fd,char* buf, int l) { - +static int default_cmd_func(int fd,char* buf, int l) +{ while(1) { int r = read(fd,buf,l); // Error ? @@ -1009,7 +996,7 @@ mp_input_default_cmd_func(int fd,char* buf, int l) { void mp_input_add_cmd_filter(mp_input_cmd_filter func, void* ctx) { - mp_cmd_filter_t* filter = malloc(sizeof(mp_cmd_filter_t))/*, *prev*/; + mp_cmd_filter_t *filter = talloc_ptrtype(NULL, filter); filter->filter = func; filter->ctx = ctx; @@ -1018,8 +1005,8 @@ mp_input_add_cmd_filter(mp_input_cmd_filter func, void* ctx) { } -static char* -mp_input_find_bind_for_key(const mp_cmd_bind_t* binds, int n,int* keys) { +static char *find_bind_for_key(const mp_cmd_bind_t* binds, int n,int* keys) +{ int j; if (n <= 0) return NULL; @@ -1037,9 +1024,10 @@ mp_input_find_bind_for_key(const mp_cmd_bind_t* binds, int n,int* keys) { return binds[j].cmd; } -static mp_cmd_bind_section_t* -mp_input_get_bind_section(char *section) { - mp_cmd_bind_section_t* bind_section = cmd_binds_section; +static mp_cmd_bind_section_t *get_bind_section(struct input_ctx *ictx, + char *section) +{ + mp_cmd_bind_section_t *bind_section = ictx->cmd_bind_sections; if (section==NULL) section="default"; while (bind_section) { @@ -1048,36 +1036,39 @@ mp_input_get_bind_section(char *section) { bind_section=bind_section->next; } if(bind_section) { - bind_section->next=malloc(sizeof(mp_cmd_bind_section_t)); + bind_section->next = talloc_ptrtype(ictx, bind_section->next); bind_section=bind_section->next; } else { - cmd_binds_section=malloc(sizeof(mp_cmd_bind_section_t)); - bind_section=cmd_binds_section; + ictx->cmd_bind_sections = talloc_ptrtype(ictx, ictx->cmd_bind_sections); + bind_section = ictx->cmd_bind_sections; } bind_section->cmd_binds=NULL; - bind_section->section=strdup(section); + bind_section->section = talloc_strdup(bind_section, section); bind_section->next=NULL; return bind_section; } -static mp_cmd_t* -mp_input_get_cmd_from_keys(int n,int* keys, int paused) { +static mp_cmd_t *get_cmd_from_keys(struct input_ctx *ictx, int n, int *keys, + int paused) +{ char* cmd = NULL; mp_cmd_t* ret; + char key_buf[12]; - if(cmd_binds) - cmd = mp_input_find_bind_for_key(cmd_binds,n,keys); - if(cmd_binds_default && cmd == NULL) - cmd = mp_input_find_bind_for_key(cmd_binds_default,n,keys); + if (ictx->cmd_binds) + cmd = find_bind_for_key(ictx->cmd_binds, n, keys); + if (ictx->cmd_binds_default && cmd == NULL) + cmd = find_bind_for_key(ictx->cmd_binds_default, n, keys); if(cmd == NULL) - cmd = mp_input_find_bind_for_key(def_cmd_binds,n,keys); + cmd = find_bind_for_key(def_cmd_binds,n,keys); if(cmd == NULL) { - mp_msg(MSGT_INPUT,MSGL_WARN,MSGTR_NoBindFound,mp_input_get_key_name(keys[0])); + mp_msg(MSGT_INPUT,MSGL_WARN,MSGTR_NoBindFound, get_key_name(keys[0], + key_buf)); if(n > 1) { int s; for(s=1; s < n; s++) - mp_msg(MSGT_INPUT,MSGL_WARN,"-%s",mp_input_get_key_name(keys[s])); + mp_msg(MSGT_INPUT,MSGL_WARN,"-%s", get_key_name(keys[s], key_buf)); } mp_msg(MSGT_INPUT,MSGL_WARN," \n"); return NULL; @@ -1085,11 +1076,13 @@ mp_input_get_cmd_from_keys(int n,int* keys, int paused) { if (strcmp(cmd, "ignore") == 0) return NULL; ret = mp_input_parse_cmd(cmd); if(!ret) { - mp_msg(MSGT_INPUT,MSGL_ERR,MSGTR_INPUT_INPUT_ErrInvalidCommandForKey,mp_input_get_key_name(key_down[0])); - if( num_key_down > 1) { + mp_msg(MSGT_INPUT,MSGL_ERR,MSGTR_INPUT_INPUT_ErrInvalidCommandForKey, + get_key_name(ictx->key_down[0], key_buf)); + if (ictx->num_key_down > 1) { unsigned int s; - for(s=1; s < num_key_down; s++) - mp_msg(MSGT_INPUT,MSGL_ERR,"-%s",mp_input_get_key_name(key_down[s])); + for(s=1; s < ictx->num_key_down; s++) + mp_msg(MSGT_INPUT,MSGL_ERR,"-%s", get_key_name(ictx->key_down[s], + key_buf)); } mp_msg(MSGT_INPUT,MSGL_ERR," : %s \n",cmd); } @@ -1097,8 +1090,7 @@ mp_input_get_cmd_from_keys(int n,int* keys, int paused) { } -static mp_cmd_t* -interpret_key(int code, int paused) +static mp_cmd_t* interpret_key(struct input_ctx *ictx, int code, int paused) { unsigned int j; mp_cmd_t* ret; @@ -1112,105 +1104,111 @@ interpret_key(int code, int paused) } if(code & MP_KEY_DOWN) { - if(num_key_down > MP_MAX_KEY_DOWN) { + if (ictx->num_key_down > MP_MAX_KEY_DOWN) { mp_msg(MSGT_INPUT,MSGL_ERR,MSGTR_INPUT_INPUT_Err2ManyKeyDowns); return NULL; } code &= ~MP_KEY_DOWN; // Check if we don't already have this key as pushed - for(j = 0; j < num_key_down; j++) { - if(key_down[j] == code) + for (j = 0; j < ictx->num_key_down; j++) { + if (ictx->key_down[j] == code) break; } - if(j != num_key_down) + if (j != ictx->num_key_down) return NULL; - key_down[num_key_down] = code; - num_key_down++; - last_key_down = GetTimer(); - ar_state = 0; + ictx->key_down[ictx->num_key_down] = code; + ictx->num_key_down++; + ictx->last_key_down = GetTimer(); + ictx->ar_state = 0; return NULL; } // key released // Check if the key is in the down key, driver which can't send push event // send only release event - for(j = 0; j < num_key_down; j++) { - if(key_down[j] == code) + for (j = 0; j < ictx->num_key_down; j++) { + if (ictx->key_down[j] == code) break; } - if(j == num_key_down) { // key was not in the down keys : add it - if(num_key_down > MP_MAX_KEY_DOWN) { + if (j == ictx->num_key_down) { // key was not in the down keys : add it + if (ictx->num_key_down > MP_MAX_KEY_DOWN) { mp_msg(MSGT_INPUT,MSGL_ERR,MSGTR_INPUT_INPUT_Err2ManyKeyDowns); return NULL; } - key_down[num_key_down] = code; - num_key_down++; - last_key_down = 1; + ictx->key_down[ictx->num_key_down] = code; + ictx->num_key_down++; + ictx->last_key_down = 1; } // We ignore key from last combination - ret = last_key_down ? mp_input_get_cmd_from_keys(num_key_down,key_down,paused) : NULL; + ret = ictx->last_key_down ? + get_cmd_from_keys(ictx, ictx->num_key_down, ictx->key_down, paused) + : NULL; // Remove the key - if(j+1 < num_key_down) - memmove(&key_down[j],&key_down[j+1],(num_key_down-(j+1))*sizeof(int)); - num_key_down--; - last_key_down = 0; - ar_state = -1; - if(ar_cmd) { - mp_cmd_free(ar_cmd); - ar_cmd = NULL; + if (j+1 < ictx->num_key_down) + memmove(&ictx->key_down[j], &ictx->key_down[j+1], + (ictx->num_key_down-(j+1))*sizeof(int)); + ictx->num_key_down--; + ictx->last_key_down = 0; + ictx->ar_state = -1; + if (ictx->ar_cmd) { + mp_cmd_free(ictx->ar_cmd); + ictx->ar_cmd = NULL; } return ret; } -static mp_cmd_t *check_autorepeat(int paused) +static mp_cmd_t *check_autorepeat(struct input_ctx *ictx, int paused) { // No input : autorepeat ? - if(ar_rate > 0 && ar_state >=0 && num_key_down > 0 && ! (key_down[num_key_down-1] & MP_NO_REPEAT_KEY)) { + if (ictx->ar_rate > 0 && ictx->ar_state >=0 && ictx->num_key_down > 0 + && !(ictx->key_down[ictx->num_key_down-1] & MP_NO_REPEAT_KEY)) { unsigned int t = GetTimer(); // First time : wait delay - if(ar_state == 0 && (t - last_key_down) >= ar_delay*1000) { - ar_cmd = mp_input_get_cmd_from_keys(num_key_down,key_down,paused); - if(!ar_cmd) { - ar_state = -1; + if (ictx->ar_state == 0 + && (t - ictx->last_key_down) >= ictx->ar_delay*1000) { + ictx->ar_cmd = get_cmd_from_keys(ictx, ictx->num_key_down, + ictx->key_down, paused); + if (!ictx->ar_cmd) { + ictx->ar_state = -1; return NULL; } - ar_state = 1; - last_ar = t; - return mp_cmd_clone(ar_cmd); + ictx->ar_state = 1; + ictx->last_ar = t; + return mp_cmd_clone(ictx->ar_cmd); // Then send rate / sec event - } else if(ar_state == 1 && (t -last_ar) >= 1000000/ar_rate) { - last_ar = t; - return mp_cmd_clone(ar_cmd); + } else if (ictx->ar_state == 1 + && (t -ictx->last_ar) >= 1000000 / ictx->ar_rate) { + ictx->last_ar = t; + return mp_cmd_clone(ictx->ar_cmd); } } return NULL; } -static mp_cmd_t *read_events(int time, int paused) +static mp_cmd_t *read_events(struct input_ctx *ictx, int time, int paused) { int i; int got_cmd = 0; - mp_cmd_t *autorepeat_cmd; -#ifdef HAVE_POSIX_SELECT - fd_set fds; -#endif - for (i = 0; i < num_key_fd; i++) + struct mp_input_fd *key_fds = ictx->key_fds; + struct mp_input_fd *cmd_fds = ictx->cmd_fds; + for (i = 0; i < ictx->num_key_fd; i++) if (key_fds[i].dead) { - mp_input_rm_key_fd(key_fds[i].fd); + mp_input_rm_key_fd(ictx, key_fds[i].fd); i--; } - for (i = 0; i < num_cmd_fd; i++) + for (i = 0; i < ictx->num_cmd_fd; i++) if (cmd_fds[i].dead || cmd_fds[i].eof) { - mp_input_rm_cmd_fd(cmd_fds[i].fd); + mp_input_rm_cmd_fd(ictx, cmd_fds[i].fd); i--; } else if (cmd_fds[i].got_cmd) got_cmd = 1; #ifdef HAVE_POSIX_SELECT + fd_set fds; FD_ZERO(&fds); if (!got_cmd) { int max_fd = 0, num_fd = 0; - for (i = 0; i < num_key_fd; i++) { + for (i = 0; i < ictx->num_key_fd; i++) { if (key_fds[i].no_select) continue; if (key_fds[i].fd > max_fd) @@ -1218,7 +1216,7 @@ static mp_cmd_t *read_events(int time, int paused) FD_SET(key_fds[i].fd, &fds); num_fd++; } - for (i = 0; i < num_cmd_fd; i++) { + for (i = 0; i < ictx->num_cmd_fd; i++) { if (cmd_fds[i].no_select) continue; if (cmd_fds[i].fd > max_fd) @@ -1249,25 +1247,15 @@ static mp_cmd_t *read_events(int time, int paused) #endif - for (i = 0; i < num_key_fd; i++) { - int code; + for (i = 0; i < ictx->num_key_fd; i++) { #ifdef HAVE_POSIX_SELECT if (!key_fds[i].no_select && !FD_ISSET(key_fds[i].fd, &fds)) continue; #endif - if (key_fds[i].no_readfunc_retval) { // getch2 handler special-cased for now - ((void (*)(void))key_fds[i].read_func)(); - if (cmd_queue_length) - return NULL; - code = mplayer_get_key(0); - if (code < 0) - code = MP_INPUT_NOTHING; - } - else - code = ((mp_key_func_t)key_fds[i].read_func)(key_fds[i].fd); + int code = key_fds[i].read_func.key(key_fds[i].ctx, key_fds[i].fd); if (code >= 0) { - mp_cmd_t *ret = interpret_key(code, paused); + mp_cmd_t *ret = interpret_key(ictx, code, paused); if (ret) return ret; } @@ -1280,22 +1268,21 @@ static mp_cmd_t *read_events(int time, int paused) key_fds[i].dead = 1; } } - autorepeat_cmd = check_autorepeat(paused); + mp_cmd_t *autorepeat_cmd = check_autorepeat(ictx, paused); if (autorepeat_cmd) return autorepeat_cmd; - for (i = 0; i < num_cmd_fd; i++) { - char *cmd; - int r; + for (i = 0; i < ictx->num_cmd_fd; i++) { #ifdef HAVE_POSIX_SELECT if (!cmd_fds[i].no_select && !FD_ISSET(cmd_fds[i].fd, &fds) && !cmd_fds[i].got_cmd) continue; #endif - r = mp_input_read_cmd(&cmd_fds[i], &cmd); + char *cmd; + int r = read_cmd(&cmd_fds[i], &cmd); if (r >= 0) { mp_cmd_t *ret = mp_input_parse_cmd(cmd); - free(cmd); + talloc_free(cmd); if (ret) return ret; } @@ -1310,28 +1297,28 @@ static mp_cmd_t *read_events(int time, int paused) } -int -mp_input_queue_cmd(mp_cmd_t* cmd) { - if(!cmd || cmd_queue_length >= CMD_QUEUE_SIZE) +int mp_input_queue_cmd(struct input_ctx *ictx, mp_cmd_t* cmd) +{ + if (!cmd || ictx->cmd_queue_length >= CMD_QUEUE_SIZE) return 0; - cmd_queue[cmd_queue_end] = cmd; - cmd_queue_end = (cmd_queue_end + 1) % CMD_QUEUE_SIZE; - cmd_queue_length++; + ictx->cmd_queue[ictx->cmd_queue_end] = cmd; + ictx->cmd_queue_end = (ictx->cmd_queue_end + 1) % CMD_QUEUE_SIZE; + ictx->cmd_queue_length++; return 1; } -static mp_cmd_t* -mp_input_get_queued_cmd(int peek_only) { +static mp_cmd_t *get_queued_cmd(struct input_ctx *ictx, int peek_only) +{ mp_cmd_t* ret; - if(cmd_queue_length == 0) + if (ictx->cmd_queue_length == 0) return NULL; - ret = cmd_queue[cmd_queue_start]; + ret = ictx->cmd_queue[ictx->cmd_queue_start]; if (!peek_only) { - cmd_queue_length--; - cmd_queue_start = (cmd_queue_start + 1) % CMD_QUEUE_SIZE; + ictx->cmd_queue_length--; + ictx->cmd_queue_start = (ictx->cmd_queue_start + 1) % CMD_QUEUE_SIZE; } return ret; @@ -1341,8 +1328,9 @@ mp_input_get_queued_cmd(int peek_only) { * \param peek_only when set, the returned command stays in the queue. * Do not free the returned cmd whe you set this! */ -mp_cmd_t* -mp_input_get_cmd(int time, int paused, int peek_only) { +mp_cmd_t *mp_input_get_cmd(struct input_ctx *ictx, int time, int paused, + int peek_only) +{ mp_cmd_t* ret = NULL; mp_cmd_filter_t* cf; int from_queue; @@ -1351,13 +1339,13 @@ mp_input_get_cmd(int time, int paused, int peek_only) { return mp_input_parse_cmd("quit 1"); while(1) { from_queue = 1; - ret = mp_input_get_queued_cmd(peek_only); + ret = get_queued_cmd(ictx, peek_only); if(ret) break; from_queue = 0; - ret = read_events(time, paused); + ret = read_events(ictx, time, paused); if (!ret) { from_queue = 1; - ret = mp_input_get_queued_cmd(peek_only); + ret = get_queued_cmd(ictx, peek_only); } break; } @@ -1367,34 +1355,21 @@ mp_input_get_cmd(int time, int paused, int peek_only) { if(cf->filter(ret,paused,cf->ctx)) { if (peek_only && from_queue) // The filter ate the cmd, so we remove it from queue - ret = mp_input_get_queued_cmd(0); + ret = get_queued_cmd(ictx, 0); mp_cmd_free(ret); return NULL; } } if (!from_queue && peek_only) - mp_input_queue_cmd(ret); + mp_input_queue_cmd(ictx, ret); return ret; } void mp_cmd_free(mp_cmd_t* cmd) { - int i; -//#ifdef MP_DEBUG -// assert(cmd != NULL); -//#endif - if ( !cmd ) return; - - if(cmd->name) - free(cmd->name); - - for(i=0; i < MP_CMD_MAX_ARGS && cmd->args[i].type != -1; i++) { - if(cmd->args[i].type == MP_CMD_ARG_STRING && cmd->args[i].v.s != NULL) - free(cmd->args[i].v.s); - } - free(cmd); + talloc_free(cmd); } mp_cmd_t* @@ -1405,22 +1380,18 @@ mp_cmd_clone(mp_cmd_t* cmd) { assert(cmd != NULL); #endif - ret = malloc(sizeof(mp_cmd_t)); - memcpy(ret,cmd,sizeof(mp_cmd_t)); - if(cmd->name) - ret->name = strdup(cmd->name); + ret = talloc_memdup(NULL, cmd, sizeof(mp_cmd_t)); + ret->name = talloc_strdup(ret, cmd->name); for(i = 0; i < MP_CMD_MAX_ARGS && cmd->args[i].type != -1; i++) { if(cmd->args[i].type == MP_CMD_ARG_STRING && cmd->args[i].v.s != NULL) - ret->args[i].v.s = strdup(cmd->args[i].v.s); + ret->args[i].v.s = talloc_strdup(ret, cmd->args[i].v.s); } return ret; } -static char key_str[12]; - -static char* -mp_input_get_key_name(int key) { +static char *get_key_name(int key, char buffer[12]) +{ int i; for(i = 0; key_names[i].name != NULL; i++) { @@ -1429,13 +1400,13 @@ mp_input_get_key_name(int key) { } if(isascii(key)) { - snprintf(key_str,12,"%c",(char)key); - return key_str; + snprintf(buffer, 12, "%c",(char)key); + return buffer; } // Print the hex key code - snprintf(key_str,12,"%#-8x",key); - return key_str; + snprintf(buffer, 12, "%#-8x",key); + return buffer; } @@ -1456,8 +1427,7 @@ mp_input_get_key_from_name(const char *name) { return -1; } -static int -mp_input_get_input_from_name(char* name,int* keys) { +static int get_input_from_name(char* name,int* keys) { char *end,*ptr; int n=0; @@ -1486,8 +1456,9 @@ mp_input_get_input_from_name(char* name,int* keys) { #define BS_MAX 256 #define SPACE_CHAR " \n\r\t" -void -mp_input_bind_keys(const int keys[MP_MAX_KEY_DOWN+1], char* cmd) { +static void bind_keys(struct input_ctx *ictx, + const int keys[MP_MAX_KEY_DOWN+1], char *cmd) +{ int i = 0,j; mp_cmd_bind_t* bind = NULL; mp_cmd_bind_section_t* bind_section = NULL; @@ -1506,7 +1477,7 @@ mp_input_bind_keys(const int keys[MP_MAX_KEY_DOWN+1], char* cmd) { for( ; cmd[0] != '\0' && strchr(SPACE_CHAR,cmd[0]) != NULL ; cmd++) /* NOTHING */; } - bind_section=mp_input_get_bind_section(section); + bind_section = get_bind_section(ictx, section); if(bind_section->cmd_binds) { for(i = 0; bind_section->cmd_binds[i].cmd != NULL ; i++) { @@ -1520,39 +1491,27 @@ mp_input_bind_keys(const int keys[MP_MAX_KEY_DOWN+1], char* cmd) { } if(!bind) { - bind_section->cmd_binds = realloc(bind_section->cmd_binds,(i+2)*sizeof(mp_cmd_bind_t)); + bind_section->cmd_binds = talloc_realloc(bind_section, + bind_section->cmd_binds, + mp_cmd_bind_t, i + 2); memset(&bind_section->cmd_binds[i],0,2*sizeof(mp_cmd_bind_t)); bind = &bind_section->cmd_binds[i]; } if(bind->cmd) - free(bind->cmd); - bind->cmd = strdup(cmd); + talloc_free(bind->cmd); + bind->cmd = talloc_strdup(bind_section->cmd_binds, cmd); memcpy(bind->input,keys,(MP_MAX_KEY_DOWN+1)*sizeof(int)); } -void -mp_input_add_binds(const mp_cmd_bind_t* list) { +static void add_binds(struct input_ctx *ictx, const mp_cmd_bind_t* list) +{ int i; for(i = 0 ; list[i].cmd ; i++) - mp_input_bind_keys(list[i].input,list[i].cmd); + bind_keys(ictx, list[i].input,list[i].cmd); } -static void -mp_input_free_binds(mp_cmd_bind_t* binds) { - int i; - - if(!binds) - return; - - for(i = 0; binds[i].cmd != NULL; i++) - free(binds[i].cmd); - - free(binds); - -} - -static int -mp_input_parse_config(char *file) { +static int parse_config(struct input_ctx *ictx, char *file) +{ int fd; int bs = 0,r,eof = 0,comments = 0; char *iter,*end; @@ -1641,7 +1600,7 @@ mp_input_parse_config(char *file) { char name[end-iter+1]; strncpy(name,iter,end-iter); name[end-iter] = '\0'; - if(! mp_input_get_input_from_name(name,keys)) { + if (!get_input_from_name(name,keys)) { mp_msg(MSGT_INPUT,MSGL_ERR,MSGTR_INPUT_INPUT_ErrUnknownKey,name); close(fd); return 0; @@ -1656,9 +1615,10 @@ mp_input_parse_config(char *file) { // Found new line if(iter[0] == '\n' || iter[0] == '\r') { int i; - mp_msg(MSGT_INPUT,MSGL_ERR,MSGTR_INPUT_INPUT_ErrNoCmdForKey,mp_input_get_key_name(keys[0])); + char key_buf[12]; + mp_msg(MSGT_INPUT,MSGL_ERR,MSGTR_INPUT_INPUT_ErrNoCmdForKey, get_key_name(keys[0], key_buf)); for(i = 1; keys[i] != 0 ; i++) - mp_msg(MSGT_INPUT,MSGL_ERR,"-%s",mp_input_get_key_name(keys[i])); + mp_msg(MSGT_INPUT,MSGL_ERR,"-%s", get_key_name(keys[i], key_buf)); mp_msg(MSGT_INPUT,MSGL_ERR,"\n"); keys[0] = 0; if(iter > buffer) { @@ -1684,7 +1644,7 @@ mp_input_parse_config(char *file) { strncpy(cmd,iter,end-iter); cmd[end-iter] = '\0'; //printf("Set bind %d => %s\n",keys[0],cmd); - mp_input_bind_keys(keys,cmd); + bind_keys(ictx, keys,cmd); n_binds++; } keys[0] = 0; @@ -1698,44 +1658,57 @@ mp_input_parse_config(char *file) { } mp_msg(MSGT_INPUT,MSGL_ERR,MSGTR_INPUT_INPUT_ErrWhyHere); close(fd); - mp_input_set_section(NULL); + mp_input_set_section(ictx, NULL); return 0; } -void -mp_input_set_section(char *name) { - mp_cmd_bind_section_t* bind_section = NULL; - - cmd_binds=NULL; - cmd_binds_default=NULL; - if(section) free(section); - if(name) section=strdup(name); else section=strdup("default"); - if((bind_section=mp_input_get_bind_section(section))) - cmd_binds=bind_section->cmd_binds; - if(strcmp(section,"default")==0) return; - if((bind_section=mp_input_get_bind_section(NULL))) - cmd_binds_default=bind_section->cmd_binds; +void mp_input_set_section(struct input_ctx *ictx, char *name) +{ + mp_cmd_bind_section_t* bind_section = NULL; + + ictx->cmd_binds = NULL; + ictx->cmd_binds_default = NULL; + if (ictx->section) + talloc_free(ictx->section); + if (name) + ictx->section = talloc_strdup(ictx, name); + else + ictx->section = talloc_strdup(ictx, "default"); + if ((bind_section = get_bind_section(ictx, ictx->section))) + ictx->cmd_binds = bind_section->cmd_binds; + if (strcmp(ictx->section, "default") == 0) + return; + if ((bind_section = get_bind_section(ictx, NULL))) + ictx->cmd_binds_default = bind_section->cmd_binds; } -char* -mp_input_get_section(void) { - return section; +char *mp_input_get_section(struct input_ctx *ictx) +{ + return ictx->section; } -void -mp_input_init(int use_gui) { +struct input_ctx *mp_input_init(struct input_conf *input_conf, int use_gui) +{ + struct input_ctx *ictx = talloc_ptrtype(NULL, ictx); + *ictx = (struct input_ctx){ + .ar_state = -1, + .ar_delay = input_conf->ar_delay, + .ar_rate = input_conf->ar_rate, + }; + char* file; #ifdef CONFIG_GUI if(use_gui) - mp_input_add_binds(gui_def_cmd_binds); + add_binds(ictx, gui_def_cmd_binds); #endif + char *config_file = input_conf->config_file; file = config_file[0] != '/' ? get_path(config_file) : config_file; if(!file) - return; + return ictx; - if( !mp_input_parse_config(file)) { + if (!parse_config(ictx, file)) { // free file if it was allocated by get_path(), // before it gets overwritten if( file != config_file) @@ -1744,7 +1717,7 @@ mp_input_init(int use_gui) { } // Try global conf dir file = MPLAYER_CONFDIR "/input.conf"; - if(! mp_input_parse_config(file)) + if (!parse_config(ictx, file)) mp_msg(MSGT_INPUT,MSGL_V,"Falling back on default (hardcoded) input config\n"); } else @@ -1755,87 +1728,89 @@ mp_input_init(int use_gui) { } #ifdef CONFIG_JOYSTICK - if(use_joystick) { - int fd = mp_input_joystick_init(js_dev); + if (input_conf->use_joystick) { + int fd = mp_input_joystick_init(input_conf->js_dev); if(fd < 0) mp_msg(MSGT_INPUT,MSGL_ERR,MSGTR_INPUT_INPUT_ErrCantInitJoystick); else - mp_input_add_key_fd(fd,1,mp_input_joystick_read,(mp_close_func_t)close); + mp_input_add_key_fd(ictx, fd, 1, mp_input_joystick_read, + (mp_close_func_t)close,NULL); } #endif #ifdef CONFIG_LIRC - if(use_lirc) { + if (input_conf->use_lirc) { int fd = mp_input_lirc_init(); if(fd > 0) - mp_input_add_cmd_fd(fd,0,mp_input_lirc_read,mp_input_lirc_close); + mp_input_add_cmd_fd(ictx, fd, 0, mp_input_lirc_read, + mp_input_lirc_close); } #endif #ifdef CONFIG_LIRCC - if(use_lircc) { + if (input_conf->use_lircc) { int fd = lircc_init("mplayer", NULL); if(fd >= 0) - mp_input_add_cmd_fd(fd,1,NULL,(mp_close_func_t)lircc_cleanup); + mp_input_add_cmd_fd(ictx, fd, 1, NULL, (mp_close_func_t)lircc_cleanup); } #endif #ifdef CONFIG_APPLE_REMOTE - if(use_ar) { + if (input_conf->use_ar) { if(mp_input_ar_init() < 0) mp_msg(MSGT_INPUT,MSGL_ERR,MSGTR_INPUT_INPUT_ErrCantInitAppleRemote); else - mp_input_add_key_fd(-1,0,mp_input_ar_read,mp_input_ar_close); + mp_input_add_key_fd(ictx, -1, 0, mp_input_ar_read, mp_input_ar_close, + NULL); } #endif #ifdef CONFIG_APPLE_IR - if(use_ar) { - int fd = mp_input_appleir_init(ar_dev); + if (input_conf->use_ar) { + int fd = mp_input_appleir_init(input_conf->ar_dev); if(fd < 0) mp_msg(MSGT_INPUT,MSGL_ERR,MSGTR_INPUT_INPUT_ErrCantInitAppleRemote); else - mp_input_add_key_fd(fd,1,mp_input_appleir_read,(mp_close_func_t)close); + mp_input_add_key_fd(ictx, fd, 1, mp_input_appleir_read, + (mp_close_func_t)close, NULL); } #endif - if(in_file) { + if (input_conf->in_file) { struct stat st; - if(stat(in_file,&st)) - mp_msg(MSGT_INPUT,MSGL_ERR,MSGTR_INPUT_INPUT_ErrCantStatFile,in_file,strerror(errno)); + if (stat(input_conf->in_file, &st)) + mp_msg(MSGT_INPUT, MSGL_ERR, MSGTR_INPUT_INPUT_ErrCantStatFile, input_conf->in_file, strerror(errno)); else { - in_file_fd = open(in_file,S_ISFIFO(st.st_mode) ? O_RDWR : O_RDONLY); + int in_file_fd = open(input_conf->in_file, + S_ISFIFO(st.st_mode) ? O_RDWR : O_RDONLY); if(in_file_fd >= 0) - mp_input_add_cmd_fd(in_file_fd,1,NULL,(mp_close_func_t)close); + mp_input_add_cmd_fd(ictx, in_file_fd, 1, NULL, + (mp_close_func_t)close); else - mp_msg(MSGT_INPUT,MSGL_ERR,MSGTR_INPUT_INPUT_ErrCantOpenFile,in_file,strerror(errno)); + mp_msg(MSGT_INPUT, MSGL_ERR, MSGTR_INPUT_INPUT_ErrCantOpenFile, + input_conf->in_file, strerror(errno)); } } - + return ictx; } -void -mp_input_uninit(void) { +void mp_input_uninit(struct input_ctx *ictx) +{ + if (!ictx) + return; + unsigned int i; - mp_cmd_bind_section_t* bind_section; - for(i=0; i < num_key_fd; i++) { - if(key_fds[i].close_func) - key_fds[i].close_func(key_fds[i].fd); + for (i=0; i < ictx->num_key_fd; i++) { + if (ictx->key_fds[i].close_func) + ictx->key_fds[i].close_func(ictx->key_fds[i].fd); } - for(i=0; i < num_cmd_fd; i++) { - if(cmd_fds[i].close_func) - cmd_fds[i].close_func(cmd_fds[i].fd); - } - while (cmd_binds_section) { - mp_input_free_binds(cmd_binds_section->cmd_binds); - free(cmd_binds_section->section); - bind_section=cmd_binds_section->next; - free(cmd_binds_section); - cmd_binds_section=bind_section; + for (i = 0; i < ictx->num_cmd_fd; i++) { + if (ictx->cmd_fds[i].close_func) + ictx->cmd_fds[i].close_func(ictx->cmd_fds[i].fd); } - cmd_binds_section=NULL; + talloc_free(ictx); } void @@ -1843,7 +1818,8 @@ mp_input_register_options(m_config_t* cfg) { m_config_register_options(cfg,mp_input_opts); } -static int mp_input_print_key_list(m_option_t* cfg) { +static int print_key_list(m_option_t* cfg) +{ int i; printf("\n"); for(i= 0; key_names[i].name != NULL ; i++) @@ -1851,7 +1827,8 @@ static int mp_input_print_key_list(m_option_t* cfg) { exit(0); } -static int mp_input_print_cmd_list(m_option_t* cfg) { +static int print_cmd_list(m_option_t* cfg) +{ const mp_cmd_t *cmd; int i,j; const char* type; @@ -1882,10 +1859,10 @@ static int mp_input_print_cmd_list(m_option_t* cfg) { exit(0); } -int -mp_input_check_interrupt(int time) { +int mp_input_check_interrupt(struct input_ctx *ictx, int time) +{ mp_cmd_t* cmd; - if((cmd = mp_input_get_cmd(time,0,1)) == NULL) + if ((cmd = mp_input_get_cmd(ictx, time, 0, 1)) == NULL) return 0; switch(cmd->id) { case MP_CMD_QUIT: @@ -1896,7 +1873,7 @@ mp_input_check_interrupt(int time) { return 1; } // remove the cmd from the queue - cmd = mp_input_get_cmd(time,0,0); + cmd = mp_input_get_cmd(ictx, time, 0, 0); mp_cmd_free(cmd); return 0; } diff --git a/input/input.h b/input/input.h index 005d02b47c..47f2560348 100644 --- a/input/input.h +++ b/input/input.h @@ -193,6 +193,8 @@ typedef enum { #define MP_MAX_KEY_DOWN 32 #endif +struct input_ctx; + typedef union mp_cmd_arg_value { int i; float f; @@ -214,21 +216,11 @@ typedef struct mp_cmd { } mp_cmd_t; -typedef struct mp_cmd_bind { - int input[MP_MAX_KEY_DOWN+1]; - char* cmd; -} mp_cmd_bind_t; - -typedef struct mp_key_name { - int key; - char* name; -} mp_key_name_t; - // These typedefs are for the drivers. They are the functions used to retrieve // the next key code or command. // These functions should return the key code or one of the error codes -typedef int (*mp_key_func_t)(int fd); +typedef int (*mp_key_func_t)(void *ctx, int fd); // These functions should act like read but they must use our error code (if needed ;-) typedef int (*mp_cmd_func_t)(int fd,char* dest,int size); // These are used to close the driver @@ -246,25 +238,20 @@ typedef int (*mp_input_cmd_filter)(mp_cmd_t* cmd, int paused, void* ctx); // fd will be used. // The last arg can be NULL if nothing is needed to close the driver. The close // function can be used -int -mp_input_add_cmd_fd(int fd, int select, mp_cmd_func_t read_func, mp_close_func_t close_func); +int mp_input_add_cmd_fd(struct input_ctx *ictx, int fd, int select, + mp_cmd_func_t read_func, mp_close_func_t close_func); // This removes a cmd driver, you usually don't need to use it. -void -mp_input_rm_cmd_fd(int fd); +void mp_input_rm_cmd_fd(struct input_ctx *ictx, int fd); // The args are the same as for the key's drivers. If you don't use any valid fd you MUST // give a read_func. -int -mp_input_add_key_fd(int fd, int select, mp_key_func_t read_func, mp_close_func_t close_func); +int mp_input_add_key_fd(struct input_ctx *ictx, int fd, int select, + mp_key_func_t read_func, mp_close_func_t close_func, + void *ctx); // As for the cmd one you usually don't need this function. -void -mp_input_rm_key_fd(int fd); - -int mp_input_add_event_fd(int fd, void (*read_func)(void)); - -void mp_input_rm_event_fd(int fd); +void mp_input_rm_key_fd(struct input_ctx *ictx, int fd); /// Get input key from its name. int mp_input_get_key_from_name(const char *name); @@ -272,13 +259,12 @@ int mp_input_get_key_from_name(const char *name); // This function can be used to put a command in the system again. It's used by libmpdemux // when it performs a blocking operation to resend the command it received to the main // loop. -int -mp_input_queue_cmd(mp_cmd_t* cmd); +int mp_input_queue_cmd(struct input_ctx *ictx, mp_cmd_t* cmd); // This function retrieves the next available command waiting no more than time msec. // If pause is true, the next input will always return a pause command. mp_cmd_t* -mp_input_get_cmd(int time, int paused, int peek_only); +mp_input_get_cmd(struct input_ctx *ictx, int time, int paused, int peek_only); mp_cmd_t* mp_input_parse_cmd(char* str); @@ -287,7 +273,7 @@ mp_input_parse_cmd(char* str); * Parse and queue commands separated by '\n'. * @return count of commands new queued. */ -int mp_input_parse_and_queue_cmds(const char *str); +int mp_input_parse_and_queue_cmds(struct input_ctx *ictx, const char *str); /// These filters allow you to process the command before MPlayer. /// If a filter returns a true value mp_input_get_cmd will return NULL. @@ -304,23 +290,23 @@ mp_cmd_t* mp_cmd_clone(mp_cmd_t* cmd); // Set current input section -void -mp_input_set_section(char *name); +void mp_input_set_section(struct input_ctx *ictx, char *name); // Get current input section -char* -mp_input_get_section(void); +char *mp_input_get_section(struct input_ctx *ictx); // When you create a new driver you should add it in these 2 functions. -void -mp_input_init(int use_gui); +struct input_conf; +struct input_ctx *mp_input_init(struct input_conf *input_conf, int use_gui); -void -mp_input_uninit(void); +void mp_input_uninit(struct input_ctx *ictx); + +struct m_config; +void mp_input_register_options(struct m_config *cfg); // Interruptible usleep: (used by libmpdemux) int -mp_input_check_interrupt(int time); +mp_input_check_interrupt(struct input_ctx *ictx, int time); extern int async_quit_request; diff --git a/input/joystick.c b/input/joystick.c index 772b097364..b49214c95c 100644 --- a/input/joystick.c +++ b/input/joystick.c @@ -90,7 +90,7 @@ int mp_input_joystick_init(char* dev) { return fd; } -int mp_input_joystick_read(int fd) { +int mp_input_joystick_read(void *ctx, int fd) { struct js_event ev; int l=0; diff --git a/input/joystick.h b/input/joystick.h index dbb269035f..996f0fed21 100644 --- a/input/joystick.h +++ b/input/joystick.h @@ -55,6 +55,6 @@ int mp_input_joystick_init(char* dev); -int mp_input_joystick_read(int fd); +int mp_input_joystick_read(void *ctx, int fd); #endif /* MPLAYER_JOYSTICK_H */ diff --git a/libaf/af.h b/libaf/af.h index 71dd023fa5..f5967d8bee 100644 --- a/libaf/af.h +++ b/libaf/af.h @@ -108,7 +108,7 @@ typedef struct af_cfg_s{ }af_cfg_t; // Current audio stream -typedef struct af_stream_s +typedef struct af_stream { // The first and last filter in the list af_instance_t* first; diff --git a/libao2/ao_alsa.c b/libao2/ao_alsa.c index 6d2e1f959f..194890ff9a 100644 --- a/libao2/ao_alsa.c +++ b/libao2/ao_alsa.c @@ -84,6 +84,7 @@ static int ao_noblock = 0; static int open_mode; static int alsa_can_pause = 0; +static snd_pcm_sframes_t prepause_frames; #define ALSA_DEVICE_SIZE 256 @@ -348,6 +349,8 @@ static int init(int rate_hz, int channels, int format, int flags) mp_msg(MSGT_AO,MSGL_V,"alsa-init: compiled for ALSA-%s\n", SND_LIB_VERSION_STR); #endif + prepause_frames = 0; + snd_lib_error_set_handler(alsa_error_handler); ao_data.samplerate = rate_hz; @@ -767,6 +770,10 @@ static void audio_pause(void) } mp_msg(MSGT_AO,MSGL_V,"alsa-pause: pause supported by hardware\n"); } else { + if (snd_pcm_delay(alsa_handler, &prepause_frames) < 0 + || prepause_frames < 0) + prepause_frames = 0; + if ((err = snd_pcm_drop(alsa_handler)) < 0) { mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_PcmDropError, snd_strerror(err)); @@ -796,6 +803,11 @@ static void audio_resume(void) mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_PcmPrepareError, snd_strerror(err)); return; } + if (prepause_frames) { + void *silence = calloc(prepause_frames, bytes_per_sample); + play(silence, prepause_frames * bytes_per_sample, 0); + free(silence); + } } } @@ -804,6 +816,7 @@ static void reset(void) { int err; + prepause_frames = 0; if ((err = snd_pcm_drop(alsa_handler)) < 0) { mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_PcmPrepareError, snd_strerror(err)); @@ -879,10 +892,10 @@ static int get_space(void) return 0; } - ret = snd_pcm_status_get_avail(status) * bytes_per_sample; - if (ret > ao_data.buffersize) // Buffer underrun? - ret = ao_data.buffersize; - return ret; + unsigned space = snd_pcm_status_get_avail(status) * bytes_per_sample; + if (space > ao_data.buffersize) // Buffer underrun? + space = ao_data.buffersize; + return space; } /* delay in seconds between first and last sample in buffer */ diff --git a/libao2/ao_ivtv.c b/libao2/ao_ivtv.c index 96ea563c96..71b58c0637 100644 --- a/libao2/ao_ivtv.c +++ b/libao2/ao_ivtv.c @@ -147,7 +147,7 @@ get_space (void) static int play (void *data, int len, int flags) { - int ivtv_write (unsigned char *data, int len); + int ivtv_write (const unsigned char *data, int len); if (ao_data.format != AF_FORMAT_MPEG2) return 0; diff --git a/libao2/ao_mpegpes.c b/libao2/ao_mpegpes.c index 38f30b1c16..5af124fd42 100644 --- a/libao2/ao_mpegpes.c +++ b/libao2/ao_mpegpes.c @@ -208,7 +208,7 @@ static int preinit(const char *arg) return vo_mpegpes_fd2; } -static int my_ao_write(unsigned char* data,int len){ +static int my_ao_write(const unsigned char* data,int len){ int orig_len = len; #ifdef CONFIG_DVB #define NFD 1 @@ -303,8 +303,6 @@ static void audio_resume(void) { } -void send_pes_packet(unsigned char* data,int len,int id,int timestamp); -void send_lpcm_packet(unsigned char* data,int len,int id,int timestamp,int freq_id); extern int vo_pts; // return: how many bytes can be played without blocking diff --git a/libao2/ao_sdl.c b/libao2/ao_sdl.c index 97a70d4adf..645c9e9685 100644 --- a/libao2/ao_sdl.c +++ b/libao2/ao_sdl.c @@ -159,7 +159,7 @@ static int control(int cmd,void *arg){ } // SDL Callback function -void outputaudio(void *unused, Uint8 *stream, int len) { +static void outputaudio(void *unused, Uint8 *stream, int len) { //SDL_MixAudio(stream, read_buffer(buffers, len), len, SDL_MIX_MAXVOLUME); //if(!full_buffers) printf("SDL: Buffer underrun!\n"); diff --git a/libao2/ao_v4l2.c b/libao2/ao_v4l2.c index b1b510ea46..eca46f01ac 100644 --- a/libao2/ao_v4l2.c +++ b/libao2/ao_v4l2.c @@ -144,7 +144,7 @@ get_space (void) static int play (void *data, int len, int flags) { - int v4l2_write (unsigned char *data, int len); + int v4l2_write (const unsigned char *data, int len); if (ao_data.format != AF_FORMAT_MPEG2) return 0; diff --git a/libao2/audio_out.c b/libao2/audio_out.c index 7fc9fdb6b4..ee62ebc016 100644 --- a/libao2/audio_out.c +++ b/libao2/audio_out.c @@ -25,7 +25,6 @@ #include "mp_msg.h" #include "help_mp.h" -#include "mplayer.h" /* for exit_player() */ // there are some globals: ao_data_t ao_data={0,0,0,0,OUTBURST,-1,0}; @@ -137,10 +136,6 @@ const ao_functions_t* init_best_audio_out(char** ao_list,int use_plugin,int rate while(ao_list[0][0]){ char* ao=ao_list[0]; int ao_len; - if (strncmp(ao, "alsa9", 5) == 0 || strncmp(ao, "alsa1x", 6) == 0) { - mp_msg(MSGT_AO, MSGL_FATAL, MSGTR_AO_ALSA9_1x_Removed); - exit_player(NULL); - } if (ao_subdevice) { free(ao_subdevice); ao_subdevice = NULL; diff --git a/libao2/audio_out.h b/libao2/audio_out.h index 3312ab0aa7..e7494c89da 100644 --- a/libao2/audio_out.h +++ b/libao2/audio_out.h @@ -47,8 +47,7 @@ typedef struct ao_functions_s } ao_functions_t; /* global data used by mplayer and plugins */ -typedef struct ao_data_s -{ +typedef struct ao_data { int samplerate; int channels; int format; diff --git a/libass/ass_cache.c b/libass/ass_cache.c index 41645c4a48..8c4c91e739 100644 --- a/libass/ass_cache.c +++ b/libass/ass_cache.c @@ -228,6 +228,13 @@ void ass_font_cache_done(void) hashmap_done(font_cache); } + +// Create hash/compare functions for bitmap and glyph +#define CREATE_HASH_FUNCTIONS +#include "ass_cache_template.c" +#define CREATE_COMPARISON_FUNCTIONS +#include "ass_cache_template.c" + //--------------------------------- // bitmap cache @@ -263,7 +270,8 @@ void ass_bitmap_cache_init(void) bitmap_cache = hashmap_init(sizeof(bitmap_hash_key_t), sizeof(bitmap_hash_val_t), 0xFFFF + 13, - bitmap_hash_dtor, NULL, NULL); + bitmap_hash_dtor, bitmap_compare, + bitmap_hash); } void ass_bitmap_cache_done(void) @@ -311,7 +319,7 @@ void ass_glyph_cache_init(void) glyph_cache = hashmap_init(sizeof(glyph_hash_key_t), sizeof(glyph_hash_val_t), 0xFFFF + 13, - glyph_hash_dtor, NULL, NULL); + glyph_hash_dtor, glyph_compare, glyph_hash); } void ass_glyph_cache_done(void) diff --git a/libass/ass_cache.h b/libass/ass_cache.h index fdb8a641c9..a76d935992 100644 --- a/libass/ass_cache.h +++ b/libass/ass_cache.h @@ -33,25 +33,9 @@ void* ass_font_cache_add(ass_font_t* font); void ass_font_cache_done(void); -// describes a bitmap; bitmaps with equivalents structs are considered identical -typedef struct bitmap_hash_key_s { - char bitmap; // bool : true = bitmap, false = outline - ass_font_t* font; - double size; // font size - uint32_t ch; // character code - unsigned outline; // border width, 16.16 fixed point value - int bold, italic; - char be; // blur edges - double blur; // gaussian blur - - unsigned scale_x, scale_y; // 16.16 - int frx, fry, frz; // signed 16.16 - int shift_x, shift_y; // shift vector that was added to glyph before applying rotation - // = 0, if frx = fry = frx = 0 - // = (glyph base point) - (rotation origin), otherwise - - FT_Vector advance; // subpixel shift vector -} bitmap_hash_key_t; +// Create definitions for bitmap_hash_key and glyph_hash_key +#define CREATE_STRUCT_DEFINITIONS +#include "ass_cache_template.c" typedef struct bitmap_hash_val_s { bitmap_t* bm; // the actual bitmaps @@ -65,17 +49,6 @@ bitmap_hash_val_t* cache_find_bitmap(bitmap_hash_key_t* key); void ass_bitmap_cache_reset(void); void ass_bitmap_cache_done(void); -// describes an outline glyph -typedef struct glyph_hash_key_s { - ass_font_t* font; - double size; // font size - uint32_t ch; // character code - int bold, italic; - unsigned scale_x, scale_y; // 16.16 - FT_Vector advance; // subpixel shift vector - unsigned outline; // border width, 16.16 -} glyph_hash_key_t; - typedef struct glyph_hash_val_s { FT_Glyph glyph; FT_Glyph outline_glyph; diff --git a/libass/ass_cache_template.c b/libass/ass_cache_template.c new file mode 100644 index 0000000000..7f9ec95f57 --- /dev/null +++ b/libass/ass_cache_template.c @@ -0,0 +1,88 @@ +#ifdef CREATE_STRUCT_DEFINITIONS +#undef CREATE_STRUCT_DEFINITIONS +#define START(funcname, structname) \ + typedef struct structname { +#define GENERIC(type, member) \ + type member; +#define FTVECTOR(member) \ + FT_Vector member; +#define END(typedefnamename) \ + } typedefnamename; + +#elif defined(CREATE_COMPARISON_FUNCTIONS) +#undef CREATE_COMPARISON_FUNCTIONS +#define START(funcname, structname) \ + static int funcname##_compare(void *key1, void *key2, size_t key_size) \ + { \ + struct structname *a = key1; \ + struct structname *b = key2; \ + return // conditions follow +#define GENERIC(type, member) \ + a->member == b->member && +#define FTVECTOR(member) \ + a->member.x == b->member.x && a->member.y == b->member.y && +#define END(typedefname) \ + 1; \ + } + +#elif defined(CREATE_HASH_FUNCTIONS) +#undef CREATE_HASH_FUNCTIONS +#define START(funcname, structname) \ + static unsigned funcname##_hash(void *buf, size_t len) \ + { \ + struct structname *p = buf; \ + unsigned hval = FNV1_32A_INIT; +#define GENERIC(type, member) \ + hval = fnv_32a_buf(&p->member, sizeof(p->member), hval); +#define FTVECTOR(member) GENERIC(, member.x); GENERIC(, member.y); +#define END(typedefname) \ + return hval; \ + } + +#else +#error missing defines +#endif + + + +// describes a bitmap; bitmaps with equivalents structs are considered identical +START(bitmap, bipmap_hash_key_s) + GENERIC(char, bitmap) // bool : true = bitmap, false = outline + GENERIC(ass_font_t *, font) + GENERIC(double, size) // font size + GENERIC(uint32_t, ch) // character code + GENERIC(unsigned, outline) // border width, 16.16 fixed point value + GENERIC(int, bold) + GENERIC(int, italic) + GENERIC(char, be) // blur edges + GENERIC(double, blur) // gaussian blur + GENERIC(unsigned, scale_x) // 16.16 + GENERIC(unsigned, scale_y) // 16.16 + GENERIC(int, frx) // signed 16.16 + GENERIC(int, fry) // signed 16.16 + GENERIC(int, frz) // signed 16.16 + // shift vector that was added to glyph before applying rotation + // = 0, if frx = fry = frx = 0 + // = (glyph base point) - (rotation origin), otherwise + GENERIC(int, shift_x) + GENERIC(int, shift_y) + FTVECTOR(advance) // subpixel shift vector +END(bitmap_hash_key_t) + +// describes an outline glyph +START(glyph, glyph_hash_key_s) + GENERIC(ass_font_t *, font) + GENERIC(double, size) // font size + GENERIC(uint32_t, ch) // character code + GENERIC(int, bold) + GENERIC(int, italic) + GENERIC(unsigned, scale_x) // 16.16 + GENERIC(unsigned, scale_y) // 16.16 + FTVECTOR(advance) // subpixel shift vector + GENERIC(unsigned, outline) // border width, 16.16 +END(glyph_hash_key_t) + +#undef START +#undef GENERIC +#undef FTVECTOR +#undef END diff --git a/libass/ass_render.c b/libass/ass_render.c index afd6e8f2fa..b3ef0ca76f 100644 --- a/libass/ass_render.c +++ b/libass/ass_render.c @@ -894,7 +894,10 @@ static char* parse_tag(char* p, double pwr) { v2 = strtol(p, &p, 10); skip(')'); mp_msg(MSGT_ASS, MSGL_DBG2, "pos(%d, %d)\n", v1, v2); - if (render_context.evt_type != EVENT_POSITIONED) { + if (render_context.evt_type == EVENT_POSITIONED) { + mp_msg(MSGT_ASS, MSGL_V, "Subtitle has a new \\pos " + "after \\move or \\pos, ignoring\n"); + } else { render_context.evt_type = EVENT_POSITIONED; render_context.detect_collisions = 0; render_context.pos_x = v1; @@ -2085,7 +2088,7 @@ static int ass_render_event(ass_event_t* event, event_images_t* event_images) * \brief deallocate image list * \param img list pointer */ -void ass_free_images(ass_image_t* img) +static void ass_free_images(ass_image_t* img) { while (img) { ass_image_t* next = img->next; @@ -2393,7 +2396,7 @@ static void fix_collisions(event_images_t* imgs, int cnt) * \param i2 second image * \return 0 if identical, 1 if different positions, 2 if different content */ -int ass_image_compare(ass_image_t *i1, ass_image_t *i2) +static int ass_image_compare(ass_image_t *i1, ass_image_t *i2) { if (i1->w != i2->w) return 2; if (i1->h != i2->h) return 2; @@ -2411,7 +2414,7 @@ int ass_image_compare(ass_image_t *i1, ass_image_t *i2) * \param priv library handle * \return 0 if identical, 1 if different positions, 2 if different content */ -int ass_detect_change(ass_renderer_t *priv) +static int ass_detect_change(ass_renderer_t *priv) { ass_image_t* img, *img2; int diff; diff --git a/libmenu/menu.c b/libmenu/menu.c index 038b969e4f..9fd9a40729 100644 --- a/libmenu/menu.c +++ b/libmenu/menu.c @@ -88,13 +88,15 @@ double menu_mouse_y = -1.0; int menu_mouse_pos_updated = 0; static struct MPContext *menu_ctx = NULL; +static struct m_config *menu_mconfig = NULL; +static struct input_ctx *menu_input = NULL; static menu_def_t* menu_list = NULL; static int menu_count = 0; static menu_cmd_bindings_t *cmd_bindings = NULL; static int cmd_bindings_num = 0; -menu_cmd_bindings_t *get_cmd_bindings(const char *name) { +static menu_cmd_bindings_t *get_cmd_bindings(const char *name) { int i; for (i = 0; i < cmd_bindings_num; ++i) if (!strcasecmp(cmd_bindings[i].name, name)) @@ -102,11 +104,12 @@ menu_cmd_bindings_t *get_cmd_bindings(const char *name) { return NULL; } -static int menu_parse_config(char* buffer) { +static int menu_parse_config(char* buffer, struct m_config *mconfig) +{ char *element,*body, **attribs, *name; menu_info_t* minfo = NULL; int r,i; - ASX_Parser_t* parser = asx_parser_new(); + ASX_Parser_t* parser = asx_parser_new(mconfig); while(1) { r = asx_get_element(parser,&buffer,&element,&body,&attribs); @@ -228,7 +231,9 @@ static int menu_parse_config(char* buffer) { #define BUF_STEP 1024 #define BUF_MIN 128 #define BUF_MAX BUF_STEP*1024 -int menu_init(struct MPContext *mpctx, char* cfg_file) { +int menu_init(struct MPContext *mpctx, struct m_config *mconfig, + struct input_ctx *input_ctx, char* cfg_file) +{ char* buffer = NULL; int bl = BUF_STEP, br = 0; int f, fd; @@ -267,7 +272,9 @@ int menu_init(struct MPContext *mpctx, char* cfg_file) { close(fd); menu_ctx = mpctx; - f = menu_parse_config(buffer); + menu_mconfig = mconfig; + menu_input = input_ctx; + f = menu_parse_config(buffer, mconfig); free(buffer); return f; } @@ -303,7 +310,8 @@ int menu_dflt_read_key(menu_t* menu,int cmd) { for (i = 0; i < bindings->binding_num; ++i) { if (bindings->bindings[i].key == cmd) { if (bindings->bindings[i].cmd) - mp_input_parse_and_queue_cmds(bindings->bindings[i].cmd); + mp_input_parse_and_queue_cmds(menu->input_ctx, + bindings->bindings[i].cmd); return 1; } } @@ -328,6 +336,8 @@ menu_t* menu_open(char *name) { m->priv_st = &(menu_list[i].type->priv_st); m->priv = m_struct_copy(m->priv_st,menu_list[i].cfg); m->ctx = menu_ctx; + m->mconfig = menu_mconfig; + m->input_ctx = menu_input; m->type = &menu_list[i]; if(menu_list[i].type->open(m,menu_list[i].args)) return m; @@ -725,7 +735,7 @@ int menu_text_num_lines(char* txt, int max_width) { return l; } -char* menu_text_get_next_line(char* txt, int max_width) { +static char* menu_text_get_next_line(char* txt, int max_width) { int i = 0; render_txt(txt); while (*txt) { diff --git a/libmenu/menu.h b/libmenu/menu.h index 09359dd1d6..58a3df4c46 100644 --- a/libmenu/menu.h +++ b/libmenu/menu.h @@ -31,6 +31,8 @@ struct m_struct_st; struct menu_s { struct MPContext *ctx; + struct m_config *mconfig; + struct input_ctx *input_ctx; void (*draw)(menu_t* menu,mp_image_t* mpi); void (*read_cmd)(menu_t* menu,int cmd); int (*read_key)(menu_t* menu,int cmd); @@ -70,7 +72,8 @@ typedef struct menu_info_s { #define MENU_CMD_CLICK 11 /// Global init/uninit -int menu_init(struct MPContext *mpctx, char* cfg_file); +int menu_init(struct MPContext *mpctx, struct m_config *mconfig, + struct input_ctx *input_ctx, char* cfg_file); void menu_uninit(void); /// Open a menu defined in the config file diff --git a/libmenu/menu_chapsel.c b/libmenu/menu_chapsel.c index 707908a016..35eac8833f 100644 --- a/libmenu/menu_chapsel.c +++ b/libmenu/menu_chapsel.c @@ -141,9 +141,9 @@ static void read_cmd (menu_t* menu, int cmd) case MENU_CMD_OK: { char cmdbuf[26]; sprintf(cmdbuf, "seek_chapter %d 1", menu->priv->p.current->cid); - mp_input_queue_cmd(mp_input_parse_cmd(cmdbuf)); + mp_input_queue_cmd(menu->input_ctx, mp_input_parse_cmd(cmdbuf)); if (menu->priv->auto_close) - mp_input_queue_cmd(mp_input_parse_cmd("menu hide")); + mp_input_queue_cmd(menu->input_ctx, mp_input_parse_cmd("menu hide")); break; } default: diff --git a/libmenu/menu_cmdlist.c b/libmenu/menu_cmdlist.c index 7e8f9754ea..b2faa0b583 100644 --- a/libmenu/menu_cmdlist.c +++ b/libmenu/menu_cmdlist.c @@ -71,21 +71,21 @@ static void read_cmd(menu_t* menu,int cmd) { switch(cmd) { case MENU_CMD_RIGHT: if(mpriv->p.current->right) { - mp_input_parse_and_queue_cmds(mpriv->p.current->right); + mp_input_parse_and_queue_cmds(menu->input_ctx, mpriv->p.current->right); break; } // fallback on ok if right is not defined case MENU_CMD_OK: if (mpriv->p.current->ok) - mp_input_parse_and_queue_cmds(mpriv->p.current->ok); + mp_input_parse_and_queue_cmds(menu->input_ctx, mpriv->p.current->ok); break; case MENU_CMD_LEFT: if(mpriv->p.current->left) { - mp_input_parse_and_queue_cmds(mpriv->p.current->left); + mp_input_parse_and_queue_cmds(menu->input_ctx, mpriv->p.current->left); break; } // fallback on cancel if left is not defined case MENU_CMD_CANCEL: if(mpriv->p.current->cancel) { - mp_input_parse_and_queue_cmds(mpriv->p.current->cancel); + mp_input_parse_and_queue_cmds(menu->input_ctx, mpriv->p.current->cancel); break; } default: @@ -114,7 +114,7 @@ static int parse_args(menu_t* menu,char* args) { char *element,*body, **attribs, *name; list_entry_t* m = NULL; int r; - ASX_Parser_t* parser = asx_parser_new(); + ASX_Parser_t* parser = asx_parser_new(menu->mconfig); while(1) { r = asx_get_element(parser,&args,&element,&body,&attribs); diff --git a/libmenu/menu_console.c b/libmenu/menu_console.c index af50e93a33..bba777cc4d 100644 --- a/libmenu/menu_console.c +++ b/libmenu/menu_console.c @@ -420,7 +420,7 @@ static void read_cmd(menu_t* menu,int cmd) { run_shell_cmd(menu,c->args[0].v.s); break; default: // Send the other commands to mplayer - mp_input_queue_cmd(c); + mp_input_queue_cmd(menu->input_ctx, c); } } return; diff --git a/libmenu/menu_dvbin.c b/libmenu/menu_dvbin.c index 671f27e00b..769eacf721 100644 --- a/libmenu/menu_dvbin.c +++ b/libmenu/menu_dvbin.c @@ -232,8 +232,8 @@ static void read_cmd(menu_t* menu, int cmd) if(c) { if(mpriv->auto_close) - mp_input_queue_cmd (mp_input_parse_cmd ("menu hide")); - mp_input_queue_cmd(c); + mp_input_queue_cmd(menu->input_ctx, mp_input_parse_cmd ("menu hide")); + mp_input_queue_cmd(menu->input_ctx, c); } } } diff --git a/libmenu/menu_filesel.c b/libmenu/menu_filesel.c index 6247e4073c..346937dc87 100644 --- a/libmenu/menu_filesel.c +++ b/libmenu/menu_filesel.c @@ -48,7 +48,6 @@ int menu_keepdir = 0; char *menu_chroot = NULL; -extern char *filename; struct list_entry_s { struct list_entry p; @@ -380,7 +379,7 @@ static void read_cmd(menu_t* menu,int cmd) { char *action = mpriv->p.current->d ? mpriv->dir_action:mpriv->file_action; sprintf(filename,"%s%s",mpriv->dir,mpriv->p.current->p.txt); str = replace_path(action, filename,1); - mp_input_parse_and_queue_cmds(str); + mp_input_parse_and_queue_cmds(menu->input_ctx, str); if (str != action) free(str); } @@ -391,7 +390,7 @@ static void read_cmd(menu_t* menu,int cmd) { char *str; sprintf(filename,"%s%s",mpriv->dir,mpriv->p.current->p.txt); str = replace_path(action, filename,1); - mp_input_parse_and_queue_cmds(str); + mp_input_parse_and_queue_cmds(menu->input_ctx, str); if(str != action) free(str); } break; diff --git a/libmenu/menu_param.c b/libmenu/menu_param.c index 9dc69e7d89..1ab7a59592 100644 --- a/libmenu/menu_param.c +++ b/libmenu/menu_param.c @@ -111,7 +111,7 @@ static int parse_args(menu_t* menu,char* args) { list_entry_t* m = NULL; int r; m_option_t* opt; - ASX_Parser_t* parser = asx_parser_new(); + ASX_Parser_t* parser = asx_parser_new(menu->mconfig); while(1) { @@ -236,7 +236,7 @@ static void read_cmd(menu_t* menu,int cmd) { char* txt = malloc(10 + strlen(e->menu) + 1); sprintf(txt,"set_menu %s",e->menu); c = mp_input_parse_cmd(txt); - if(c) mp_input_queue_cmd(c); + if(c) mp_input_queue_cmd(menu->input_ctx, c); return; } } diff --git a/libmenu/menu_pt.c b/libmenu/menu_pt.c index 092912060b..5c408361c7 100644 --- a/libmenu/menu_pt.c +++ b/libmenu/menu_pt.c @@ -107,8 +107,8 @@ static void read_cmd(menu_t* menu,int cmd) { c = mp_input_parse_cmd(str); if(c) { if(mpriv->auto_close) - mp_input_queue_cmd(mp_input_parse_cmd("menu hide")); - mp_input_queue_cmd(c); + mp_input_queue_cmd(menu->input_ctx, mp_input_parse_cmd("menu hide")); + mp_input_queue_cmd(menu->input_ctx, c); } else mp_msg(MSGT_GLOBAL,MSGL_WARN,MSGTR_LIBMENU_FailedToBuildCommand,str); diff --git a/libmenu/vf_menu.c b/libmenu/vf_menu.c index 33eadf25b9..f5ae5ea70d 100644 --- a/libmenu/vf_menu.c +++ b/libmenu/vf_menu.c @@ -58,15 +58,15 @@ struct vf_priv_s { int passthrough; }; -static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts); +static int put_image(struct vf_instance* vf, mp_image_t *mpi, double pts); -void vf_menu_pause_update(struct vf_instance_s* vf) { - const vo_functions_t *video_out = mpctx_get_video_out(vf->priv->current->ctx); +void vf_menu_pause_update(struct vf_instance* vf) { + const struct vo *video_out = mpctx_get_video_out(vf->priv->current->ctx); if(pause_mpi) { put_image(vf,pause_mpi, MP_NOPTS_VALUE); // Don't draw the osd atm //vf->control(vf,VFCTRL_DRAW_OSD,NULL); - video_out->flip_page(); + vo_flip_page(video_out); } } @@ -124,7 +124,7 @@ static int cmd_filter(mp_cmd_t* cmd, int paused, struct vf_priv_s * priv) { return 0; } -static void get_image(struct vf_instance_s* vf, mp_image_t *mpi){ +static void get_image(struct vf_instance* vf, mp_image_t *mpi){ mp_image_t *dmpi; if(mpi->type == MP_IMGTYPE_TEMP && (!(mpi->flags&MP_IMGFLAG_PRESERVE)) ) { @@ -141,7 +141,7 @@ static int key_cb(int code) { return menu_read_key(st_priv->current,code); } -static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){ +static int put_image(struct vf_instance* vf, mp_image_t *mpi, double pts){ mp_image_t *dmpi = NULL; if (vf->priv->passthrough) { @@ -217,7 +217,7 @@ static void uninit(vf_instance_t *vf) { } } -static int config(struct vf_instance_s* vf, int width, int height, int d_width, int d_height, +static int config(struct vf_instance* vf, int width, int height, int d_width, int d_height, unsigned int flags, unsigned int outfmt) { #ifdef CONFIG_FREETYPE // here is the right place to get screen dimensions @@ -231,8 +231,8 @@ static int config(struct vf_instance_s* vf, int width, int height, int d_width, return vf_next_config(vf,width,height,d_width,d_height,flags,outfmt); } -static int query_format(struct vf_instance_s* vf, unsigned int fmt){ - return vf_next_query_format(vf,fmt); +static int query_format(struct vf_instance* vf, unsigned int fmt){ + return vf_next_query_format(vf, fmt); } static int open_vf(vf_instance_t *vf, char* args){ diff --git a/libmpcodecs/ad.c b/libmpcodecs/ad.c index 11d6f350fe..3f191826fa 100644 --- a/libmpcodecs/ad.c +++ b/libmpcodecs/ad.c @@ -16,34 +16,34 @@ /* Missed vorbis, mad, dshow */ //extern ad_functions_t mpcodecs_ad_null; -extern ad_functions_t mpcodecs_ad_mp3lib; -extern ad_functions_t mpcodecs_ad_ffmpeg; -extern ad_functions_t mpcodecs_ad_liba52; -extern ad_functions_t mpcodecs_ad_hwac3; -extern ad_functions_t mpcodecs_ad_hwmpa; -extern ad_functions_t mpcodecs_ad_pcm; -extern ad_functions_t mpcodecs_ad_dvdpcm; -extern ad_functions_t mpcodecs_ad_alaw; -extern ad_functions_t mpcodecs_ad_imaadpcm; -extern ad_functions_t mpcodecs_ad_msadpcm; -extern ad_functions_t mpcodecs_ad_dk3adpcm; -extern ad_functions_t mpcodecs_ad_dk4adpcm; -extern ad_functions_t mpcodecs_ad_dshow; -extern ad_functions_t mpcodecs_ad_dmo; -extern ad_functions_t mpcodecs_ad_acm; -extern ad_functions_t mpcodecs_ad_msgsm; -extern ad_functions_t mpcodecs_ad_faad; -extern ad_functions_t mpcodecs_ad_libvorbis; -extern ad_functions_t mpcodecs_ad_speex; -extern ad_functions_t mpcodecs_ad_libmad; -extern ad_functions_t mpcodecs_ad_realaud; -extern ad_functions_t mpcodecs_ad_libdv; -extern ad_functions_t mpcodecs_ad_qtaudio; -extern ad_functions_t mpcodecs_ad_twin; -extern ad_functions_t mpcodecs_ad_libmusepack; -extern ad_functions_t mpcodecs_ad_libdca; +extern const ad_functions_t mpcodecs_ad_mp3lib; +extern const ad_functions_t mpcodecs_ad_ffmpeg; +extern const ad_functions_t mpcodecs_ad_liba52; +extern const ad_functions_t mpcodecs_ad_hwac3; +extern const ad_functions_t mpcodecs_ad_hwmpa; +extern const ad_functions_t mpcodecs_ad_pcm; +extern const ad_functions_t mpcodecs_ad_dvdpcm; +extern const ad_functions_t mpcodecs_ad_alaw; +extern const ad_functions_t mpcodecs_ad_imaadpcm; +extern const ad_functions_t mpcodecs_ad_msadpcm; +extern const ad_functions_t mpcodecs_ad_dk3adpcm; +extern const ad_functions_t mpcodecs_ad_dk4adpcm; +extern const ad_functions_t mpcodecs_ad_dshow; +extern const ad_functions_t mpcodecs_ad_dmo; +extern const ad_functions_t mpcodecs_ad_acm; +extern const ad_functions_t mpcodecs_ad_msgsm; +extern const ad_functions_t mpcodecs_ad_faad; +extern const ad_functions_t mpcodecs_ad_libvorbis; +extern const ad_functions_t mpcodecs_ad_speex; +extern const ad_functions_t mpcodecs_ad_libmad; +extern const ad_functions_t mpcodecs_ad_realaud; +extern const ad_functions_t mpcodecs_ad_libdv; +extern const ad_functions_t mpcodecs_ad_qtaudio; +extern const ad_functions_t mpcodecs_ad_twin; +extern const ad_functions_t mpcodecs_ad_libmusepack; +extern const ad_functions_t mpcodecs_ad_libdca; -ad_functions_t* mpcodecs_ad_drivers[] = +const ad_functions_t * const mpcodecs_ad_drivers[] = { // &mpcodecs_ad_null, #ifdef CONFIG_MP3LIB diff --git a/libmpcodecs/ad.h b/libmpcodecs/ad.h index 6f1d5e7566..a23faa24e7 100644 --- a/libmpcodecs/ad.h +++ b/libmpcodecs/ad.h @@ -7,9 +7,9 @@ typedef mp_codec_info_t ad_info_t; /* interface of video decoder drivers */ -typedef struct ad_functions_s +typedef struct ad_functions { - ad_info_t *info; + const ad_info_t *info; int (*preinit)(sh_audio_t *sh); int (*init)(sh_audio_t *sh); void (*uninit)(sh_audio_t *sh); @@ -18,7 +18,7 @@ typedef struct ad_functions_s } ad_functions_t; // NULL terminated array of all drivers -extern ad_functions_t* mpcodecs_ad_drivers[]; +extern const ad_functions_t * const mpcodecs_ad_drivers[]; // fallback if ADCTRL_RESYNC not implemented: sh_audio->a_in_buffer_len=0; #define ADCTRL_RESYNC_STREAM 1 /* resync, called after seeking! */ diff --git a/libmpcodecs/ad_acm.c b/libmpcodecs/ad_acm.c index f59ca8ddf1..3f3ad99d44 100644 --- a/libmpcodecs/ad_acm.c +++ b/libmpcodecs/ad_acm.c @@ -11,7 +11,7 @@ #include "ad_internal.h" #include "osdep/timer.h" -static ad_info_t info = +static const ad_info_t info = { "Win32/ACM decoders", "acm", diff --git a/libmpcodecs/ad_alaw.c b/libmpcodecs/ad_alaw.c index 0085b12f85..61bb7e39ec 100644 --- a/libmpcodecs/ad_alaw.c +++ b/libmpcodecs/ad_alaw.c @@ -5,7 +5,7 @@ #include "config.h" #include "ad_internal.h" -static ad_info_t info = +static const ad_info_t info = { "aLaw/uLaw audio decoder", "alaw", diff --git a/libmpcodecs/ad_dk3adpcm.c b/libmpcodecs/ad_dk3adpcm.c index 2e966a1ca5..b4eec81b5f 100644 --- a/libmpcodecs/ad_dk3adpcm.c +++ b/libmpcodecs/ad_dk3adpcm.c @@ -19,7 +19,7 @@ #include "mpbswap.h" #include "ad_internal.h" -static ad_info_t info = +static const ad_info_t info = { "Duck Corp. DK3 ADPCM decoder", "dk3adpcm", diff --git a/libmpcodecs/ad_dmo.c b/libmpcodecs/ad_dmo.c index d1133667c3..6b0c2b9ed3 100644 --- a/libmpcodecs/ad_dmo.c +++ b/libmpcodecs/ad_dmo.c @@ -9,7 +9,7 @@ #include "ad_internal.h" #include "libaf/reorder_ch.h" -static ad_info_t info = +static const ad_info_t info = { "Win32/DMO decoders", "dmo", diff --git a/libmpcodecs/ad_dshow.c b/libmpcodecs/ad_dshow.c index 24c34966bc..e9d1c450c3 100644 --- a/libmpcodecs/ad_dshow.c +++ b/libmpcodecs/ad_dshow.c @@ -8,7 +8,7 @@ #include "ad_internal.h" -static ad_info_t info = +static const ad_info_t info = { "Win32/DirectShow decoders", "dshow", diff --git a/libmpcodecs/ad_dvdpcm.c b/libmpcodecs/ad_dvdpcm.c index 1962594961..73c265666b 100644 --- a/libmpcodecs/ad_dvdpcm.c +++ b/libmpcodecs/ad_dvdpcm.c @@ -7,7 +7,7 @@ #include "help_mp.h" #include "ad_internal.h" -static ad_info_t info = +static const ad_info_t info = { "Uncompressed DVD/VOB LPCM audio decoder", "dvdpcm", diff --git a/libmpcodecs/ad_faad.c b/libmpcodecs/ad_faad.c index 226aed76f6..a7b9fbf84e 100644 --- a/libmpcodecs/ad_faad.c +++ b/libmpcodecs/ad_faad.c @@ -28,7 +28,7 @@ #include "ad_internal.h" #include "libaf/reorder_ch.h" -static ad_info_t info = +static const ad_info_t info = { "AAC (MPEG2/4 Advanced Audio Coding)", "faad", diff --git a/libmpcodecs/ad_ffmpeg.c b/libmpcodecs/ad_ffmpeg.c index c0a638db8c..560dd90c0a 100644 --- a/libmpcodecs/ad_ffmpeg.c +++ b/libmpcodecs/ad_ffmpeg.c @@ -11,7 +11,7 @@ #include "mpbswap.h" -static ad_info_t info = +static const ad_info_t info = { "FFmpeg/libavcodec audio decoders", "ffmpeg", diff --git a/libmpcodecs/ad_hwac3.c b/libmpcodecs/ad_hwac3.c index b6d688028c..6750ae0f0a 100644 --- a/libmpcodecs/ad_hwac3.c +++ b/libmpcodecs/ad_hwac3.c @@ -27,7 +27,7 @@ static int isdts = -1; -static ad_info_t info = +static const ad_info_t info = { "AC3/DTS pass-through S/PDIF", "hwac3", diff --git a/libmpcodecs/ad_hwmpa.c b/libmpcodecs/ad_hwmpa.c index 3b9bdedc8c..e17f994ead 100644 --- a/libmpcodecs/ad_hwmpa.c +++ b/libmpcodecs/ad_hwmpa.c @@ -15,7 +15,7 @@ //based on ad_hwac3.c and ad_libmad.c -static ad_info_t info = +static const ad_info_t info = { "MPEG audio pass-through (fake decoder)", "hwmpa", diff --git a/libmpcodecs/ad_imaadpcm.c b/libmpcodecs/ad_imaadpcm.c index a85cc68099..7c7f2362e5 100644 --- a/libmpcodecs/ad_imaadpcm.c +++ b/libmpcodecs/ad_imaadpcm.c @@ -62,7 +62,7 @@ static const int8_t adpcm_index[8] = // clamp a number above 16 #define CLAMP_ABOVE_16(x) if (x < 16) x = 16; -static ad_info_t info = +static const ad_info_t info = { "IMA ADPCM audio decoder", "imaadpcm", diff --git a/libmpcodecs/ad_internal.h b/libmpcodecs/ad_internal.h index 0bd01bcd6c..4018b57657 100644 --- a/libmpcodecs/ad_internal.h +++ b/libmpcodecs/ad_internal.h @@ -17,7 +17,7 @@ static void uninit(sh_audio_t *sh); static int control(sh_audio_t *sh,int cmd,void* arg, ...); static int decode_audio(sh_audio_t *sh,unsigned char *buffer,int minlen,int maxlen); -#define LIBAD_EXTERN(x) ad_functions_t mpcodecs_ad_##x = {\ +#define LIBAD_EXTERN(x) const ad_functions_t mpcodecs_ad_##x = {\ &info,\ preinit,\ init,\ diff --git a/libmpcodecs/ad_liba52.c b/libmpcodecs/ad_liba52.c index a867fae533..8ddbff8520 100644 --- a/libmpcodecs/ad_liba52.c +++ b/libmpcodecs/ad_liba52.c @@ -45,7 +45,7 @@ static sample_t a52_level = 1; float a52_drc_level = 1.0; static int a52_drc_action = DRC_NO_ACTION; -static ad_info_t info = +static const ad_info_t info = { "AC3 decoding with liba52", "liba52", @@ -56,7 +56,7 @@ static ad_info_t info = LIBAD_EXTERN(liba52) -int a52_fillbuff(sh_audio_t *sh_audio){ +static int a52_fillbuff(sh_audio_t *sh_audio){ int length=0; int flags=0; int sample_rate=0; @@ -120,7 +120,7 @@ int channels=0; return (flags&A52_LFE) ? (channels+1) : channels; } -sample_t dynrng_call (sample_t c, void *data) { +static sample_t dynrng_call (sample_t c, void *data) { // fprintf(stderr, "(%lf, %lf): %lf\n", (double)c, (double)a52_drc_level, (double)pow((double)c, a52_drc_level)); return pow((double)c, a52_drc_level); } diff --git a/libmpcodecs/ad_libdca.c b/libmpcodecs/ad_libdca.c index 1514a9953a..c167c92490 100644 --- a/libmpcodecs/ad_libdca.c +++ b/libmpcodecs/ad_libdca.c @@ -32,7 +32,7 @@ #include <dts.h> -static ad_info_t info = +static const ad_info_t info = { "DTS decoding with libdca", "libdca", diff --git a/libmpcodecs/ad_libdv.c b/libmpcodecs/ad_libdv.c index e0dfbb2166..fdfdf6cc6c 100644 --- a/libmpcodecs/ad_libdv.c +++ b/libmpcodecs/ad_libdv.c @@ -20,7 +20,7 @@ #include "ad_internal.h" -static ad_info_t info = +static const ad_info_t info = { "Raw DV Audio Decoder", "libdv", diff --git a/libmpcodecs/ad_libmad.c b/libmpcodecs/ad_libmad.c index 076359a5b6..fb20f2a77f 100644 --- a/libmpcodecs/ad_libmad.c +++ b/libmpcodecs/ad_libmad.c @@ -8,7 +8,7 @@ #include "ad_internal.h" -static ad_info_t info = { +static const ad_info_t info = { "libmad mpeg audio decoder", "libmad", "A'rpi", diff --git a/libmpcodecs/ad_libvorbis.c b/libmpcodecs/ad_libvorbis.c index 30e6604080..520b07f50a 100644 --- a/libmpcodecs/ad_libvorbis.c +++ b/libmpcodecs/ad_libvorbis.c @@ -9,7 +9,7 @@ #include "ad_internal.h" #include "libaf/reorder_ch.h" -static ad_info_t info = +static const ad_info_t info = { "Ogg/Vorbis audio decoder", #ifdef CONFIG_TREMOR diff --git a/libmpcodecs/ad_mp3lib.c b/libmpcodecs/ad_mp3lib.c index 1afb1eafbe..f10a718b09 100644 --- a/libmpcodecs/ad_mp3lib.c +++ b/libmpcodecs/ad_mp3lib.c @@ -6,7 +6,7 @@ #include "ad_internal.h" -static ad_info_t info = +static const ad_info_t info = { "MPEG layer-2, layer-3", "mp3lib", diff --git a/libmpcodecs/ad_mpc.c b/libmpcodecs/ad_mpc.c index 97ffdfed44..d994951368 100644 --- a/libmpcodecs/ad_mpc.c +++ b/libmpcodecs/ad_mpc.c @@ -16,7 +16,7 @@ #include "libaf/af_format.h" #include "libvo/fastmemcpy.h" -static ad_info_t info = +static const ad_info_t info = { "Musepack audio decoder", "mpcdec", diff --git a/libmpcodecs/ad_msadpcm.c b/libmpcodecs/ad_msadpcm.c index 11929d5e18..641992e18d 100644 --- a/libmpcodecs/ad_msadpcm.c +++ b/libmpcodecs/ad_msadpcm.c @@ -17,7 +17,7 @@ #include "mpbswap.h" #include "ad_internal.h" -static ad_info_t info = +static const ad_info_t info = { "MS ADPCM audio decoder", "msadpcm", diff --git a/libmpcodecs/ad_msgsm.c b/libmpcodecs/ad_msgsm.c index c558595656..de1ea52aa2 100644 --- a/libmpcodecs/ad_msgsm.c +++ b/libmpcodecs/ad_msgsm.c @@ -5,7 +5,7 @@ #include "config.h" #include "ad_internal.h" -static ad_info_t info = +static const ad_info_t info = { "native GSM/MSGSM audio decoder", "msgsm", diff --git a/libmpcodecs/ad_pcm.c b/libmpcodecs/ad_pcm.c index 1717cdd75d..058f6c25cb 100644 --- a/libmpcodecs/ad_pcm.c +++ b/libmpcodecs/ad_pcm.c @@ -2,12 +2,13 @@ #include <stdlib.h> #include <unistd.h> +#include "talloc.h" #include "config.h" #include "ad_internal.h" #include "libaf/af_format.h" #include "libaf/reorder_ch.h" -static ad_info_t info = +static const ad_info_t info = { "Uncompressed PCM audio decoder", "pcm", @@ -16,6 +17,11 @@ static ad_info_t info = "" }; +struct ad_pcm_context { + unsigned char *packet_ptr; + int packet_len; +}; + LIBAD_EXTERN(pcm) static int init(sh_audio_t *sh_audio) @@ -91,6 +97,7 @@ static int init(sh_audio_t *sh_audio) } if (!sh_audio->samplesize) // this would cause MPlayer to hang later sh_audio->samplesize = 2; + sh_audio->context = talloc_zero(NULL, struct ad_pcm_context); return 1; } @@ -102,6 +109,7 @@ static int preinit(sh_audio_t *sh) static void uninit(sh_audio_t *sh) { + talloc_free(sh->context); } static int control(sh_audio_t *sh,int cmd,void* arg, ...) @@ -121,12 +129,37 @@ static int control(sh_audio_t *sh,int cmd,void* arg, ...) static int decode_audio(sh_audio_t *sh_audio,unsigned char *buf,int minlen,int maxlen) { unsigned len = sh_audio->channels*sh_audio->samplesize; - len = (minlen + len - 1) / len * len; - if (len > maxlen) + minlen = (minlen + len - 1) / len * len; + if (minlen > maxlen) // if someone needs hundreds of channels adjust audio_out_minsize // based on channels in preinit() return -1; - len=demux_read_data(sh_audio->ds,buf,len); + + len = 0; + struct ad_pcm_context *ctx = sh_audio->context; + while (len < minlen) { + if (ctx->packet_len == 0) { + double pts; + int plen = ds_get_packet_pts(sh_audio->ds, &ctx->packet_ptr, &pts); + if (plen < 0) + break; + ctx->packet_len = plen; + if (pts != MP_NOPTS_VALUE) { + sh_audio->pts = pts; + sh_audio->pts_bytes = 0; + } + } + int from_stored = ctx->packet_len; + if (from_stored > minlen - len) + from_stored = minlen - len; + memcpy(buf + len, ctx->packet_ptr, from_stored); + ctx->packet_len -= from_stored; + ctx->packet_ptr += from_stored; + sh_audio->pts_bytes += from_stored; + len += from_stored; + } + if (len == 0) + len = -1; // The loop above only exits at error/EOF if (len > 0 && sh_audio->channels >= 5) { reorder_channel_nch(buf, AF_CHANNEL_LAYOUT_WAVEEX_DEFAULT, AF_CHANNEL_LAYOUT_MPLAYER_DEFAULT, diff --git a/libmpcodecs/ad_qtaudio.c b/libmpcodecs/ad_qtaudio.c index 856cb05601..2fa71c6548 100644 --- a/libmpcodecs/ad_qtaudio.c +++ b/libmpcodecs/ad_qtaudio.c @@ -15,7 +15,7 @@ #include "loader/wine/windef.h" #endif -static ad_info_t info = { +static const ad_info_t info = { "QuickTime Audio Decoder", "qtaudio", "A'rpi", diff --git a/libmpcodecs/ad_realaud.c b/libmpcodecs/ad_realaud.c index 785811bfcd..8135e21e41 100644 --- a/libmpcodecs/ad_realaud.c +++ b/libmpcodecs/ad_realaud.c @@ -14,7 +14,7 @@ #include "ad_internal.h" #include "loader/wine/windef.h" -static ad_info_t info = { +static const ad_info_t info = { "RealAudio decoder", "realaud", "Alex Beregszaszi", diff --git a/libmpcodecs/ad_sample.c b/libmpcodecs/ad_sample.c index 848152c68e..69d1440987 100644 --- a/libmpcodecs/ad_sample.c +++ b/libmpcodecs/ad_sample.c @@ -7,7 +7,7 @@ #include "config.h" #include "ad_internal.h" -static ad_info_t info = { +static const ad_info_t info = { "Sample audio decoder", // name of the driver "sample", // driver name. should be the same as filename without ad_ "A'rpi", // writer/maintainer of _this_ file diff --git a/libmpcodecs/ad_speex.c b/libmpcodecs/ad_speex.c index c41dfe8e3e..f77b0b7e89 100644 --- a/libmpcodecs/ad_speex.c +++ b/libmpcodecs/ad_speex.c @@ -11,7 +11,7 @@ #include <speex/speex_header.h> #include "ad_internal.h" -static ad_info_t info = { +static const ad_info_t info ={ "Speex audio decoder", "speex", "Reimar Döffinger", diff --git a/libmpcodecs/ad_twin.c b/libmpcodecs/ad_twin.c index 01d68a38cd..64dc4bbf78 100644 --- a/libmpcodecs/ad_twin.c +++ b/libmpcodecs/ad_twin.c @@ -11,7 +11,7 @@ #include "help_mp.h" -static ad_info_t info = +static const ad_info_t info = { "TWinVQ decoder", "vqf", diff --git a/libmpcodecs/dec_video.c b/libmpcodecs/dec_video.c index 59c67b83db..49ee002bf4 100644 --- a/libmpcodecs/dec_video.c +++ b/libmpcodecs/dec_video.c @@ -1,11 +1,12 @@ - #include "config.h" +#include "options.h" #include <stdio.h> #ifdef HAVE_MALLOC_H #include <malloc.h> #endif #include <stdlib.h> +#include <stdbool.h> #include <unistd.h> #include "mp_msg.h" @@ -39,334 +40,382 @@ extern double vout_time_usage; #include "cpudetect.h" -int field_dominance=-1; - -int divx_quality=0; +int field_dominance = -1; -vd_functions_t* mpvdec=NULL; +int divx_quality = 0; -int get_video_quality_max(sh_video_t *sh_video){ - vf_instance_t* vf=sh_video->vfilter; - if(vf){ - int ret=vf->control(vf,VFCTRL_QUERY_MAX_PP_LEVEL,NULL); - if(ret>0){ - mp_msg(MSGT_DECVIDEO,MSGL_INFO,MSGTR_UsingExternalPP,ret); - return ret; +int get_video_quality_max(sh_video_t *sh_video) +{ + vf_instance_t *vf = sh_video->vfilter; + if (vf) { + int ret = vf->control(vf, VFCTRL_QUERY_MAX_PP_LEVEL, NULL); + if (ret > 0) { + mp_msg(MSGT_DECVIDEO, MSGL_INFO, MSGTR_UsingExternalPP, ret); + return ret; + } } - } - if(mpvdec){ - int ret=mpvdec->control(sh_video,VDCTRL_QUERY_MAX_PP_LEVEL,NULL); - if(ret>0){ - mp_msg(MSGT_DECVIDEO,MSGL_INFO,MSGTR_UsingCodecPP,ret); - return ret; + const struct vd_functions *vd = sh_video->vd_driver; + if (vd) { + int ret = vd->control(sh_video, VDCTRL_QUERY_MAX_PP_LEVEL, NULL); + if (ret > 0) { + mp_msg(MSGT_DECVIDEO, MSGL_INFO, MSGTR_UsingCodecPP, ret); + return ret; + } } - } -// mp_msg(MSGT_DECVIDEO,MSGL_INFO,"[PP] Sorry, postprocessing is not available\n"); - return 0; + return 0; } -void set_video_quality(sh_video_t *sh_video,int quality){ - vf_instance_t* vf=sh_video->vfilter; - if(vf){ - int ret=vf->control(vf,VFCTRL_SET_PP_LEVEL, (void*)(&quality)); - if(ret==CONTROL_TRUE) return; // success - } - if(mpvdec) - mpvdec->control(sh_video,VDCTRL_SET_PP_LEVEL, (void*)(&quality)); +void set_video_quality(sh_video_t *sh_video, int quality) +{ + vf_instance_t *vf = sh_video->vfilter; + if (vf) { + int ret = vf->control(vf, VFCTRL_SET_PP_LEVEL, (void *) (&quality)); + if (ret == CONTROL_TRUE) + return; // success + } + const struct vd_functions *vd = sh_video->vd_driver; + if (vd) + vd->control(sh_video, VDCTRL_SET_PP_LEVEL, (void *) (&quality)); } -int set_video_colors(sh_video_t *sh_video,const char *item,int value) +int set_video_colors(sh_video_t *sh_video, const char *item, int value) { - vf_instance_t* vf=sh_video->vfilter; + vf_instance_t *vf = sh_video->vfilter; vf_equalizer_t data; data.item = item; data.value = value; - mp_dbg(MSGT_DECVIDEO,MSGL_V,"set video colors %s=%d \n", item, value); - if (vf) - { - int ret = vf->control(vf, VFCTRL_SET_EQUALIZER, &data); - if (ret == CONTROL_TRUE) - return 1; + mp_dbg(MSGT_DECVIDEO, MSGL_V, "set video colors %s=%d \n", item, value); + if (vf) { + int ret = vf->control(vf, VFCTRL_SET_EQUALIZER, &data); + if (ret == CONTROL_TRUE) + return 1; } /* try software control */ - if(mpvdec) - if( mpvdec->control(sh_video,VDCTRL_SET_EQUALIZER, item, (int *)value) - == CONTROL_OK) return 1; - mp_msg(MSGT_DECVIDEO,MSGL_V,MSGTR_VideoAttributeNotSupportedByVO_VD,item); + const struct vd_functions *vd = sh_video->vd_driver; + if (vd && + vd->control(sh_video, VDCTRL_SET_EQUALIZER, item, (int *) value) + == CONTROL_OK) + return 1; + mp_msg(MSGT_DECVIDEO, MSGL_V, MSGTR_VideoAttributeNotSupportedByVO_VD, + item); return 0; } -int get_video_colors(sh_video_t *sh_video,const char *item,int *value) +int get_video_colors(sh_video_t *sh_video, const char *item, int *value) { - vf_instance_t* vf=sh_video->vfilter; + vf_instance_t *vf = sh_video->vfilter; vf_equalizer_t data; data.item = item; - mp_dbg(MSGT_DECVIDEO,MSGL_V,"get video colors %s \n", item); - if (vf) - { + mp_dbg(MSGT_DECVIDEO, MSGL_V, "get video colors %s \n", item); + if (vf) { int ret = vf->control(vf, VFCTRL_GET_EQUALIZER, &data); - if (ret == CONTROL_TRUE){ - *value = data.value; - return 1; - } + if (ret == CONTROL_TRUE) { + *value = data.value; + return 1; + } } /* try software control */ - if(mpvdec) return mpvdec->control(sh_video,VDCTRL_GET_EQUALIZER, item, value); + const struct vd_functions *vd = sh_video->vd_driver; + if (vd) + return vd->control(sh_video, VDCTRL_GET_EQUALIZER, item, value); return 0; } -int set_rectangle(sh_video_t *sh_video,int param,int value) +int set_rectangle(sh_video_t *sh_video, int param, int value) { - vf_instance_t* vf=sh_video->vfilter; - int data[] = {param, value}; + vf_instance_t *vf = sh_video->vfilter; + int data[] = { param, value }; - mp_dbg(MSGT_DECVIDEO,MSGL_V,"set rectangle \n"); - if (vf) - { + mp_dbg(MSGT_DECVIDEO, MSGL_V, "set rectangle \n"); + if (vf) { int ret = vf->control(vf, VFCTRL_CHANGE_RECTANGLE, data); - if (ret) - return 1; + if (ret) + return 1; } return 0; } +int redraw_osd(struct sh_video *sh_video, struct osd_state *osd) +{ + struct vf_instance *vf = sh_video->vfilter; + if (vf->control(vf, VFCTRL_REDRAW_OSD, osd) == true) + return 0; + return -1; +} + void resync_video_stream(sh_video_t *sh_video) { - if(mpvdec) mpvdec->control(sh_video, VDCTRL_RESYNC_STREAM, NULL); + const struct vd_functions *vd = sh_video->vd_driver; + if (vd) + vd->control(sh_video, VDCTRL_RESYNC_STREAM, NULL); } int get_current_video_decoder_lag(sh_video_t *sh_video) { - int ret; - - if (!mpvdec) - return -1; - ret = mpvdec->control(sh_video, VDCTRL_QUERY_UNSEEN_FRAMES, NULL); + const struct vd_functions *vd = sh_video->vd_driver; + if (!vd) + return -1; + int ret = vd->control(sh_video, VDCTRL_QUERY_UNSEEN_FRAMES, NULL); if (ret >= 10) - return ret-10; + return ret - 10; return -1; } -void uninit_video(sh_video_t *sh_video){ - if(!sh_video->initialized) return; - mp_msg(MSGT_DECVIDEO,MSGL_V,MSGTR_UninitVideoStr,sh_video->codec->drv); - mpvdec->uninit(sh_video); +void uninit_video(sh_video_t *sh_video) +{ + if (!sh_video->initialized) + return; + mp_msg(MSGT_DECVIDEO, MSGL_V, MSGTR_UninitVideoStr, sh_video->codec->drv); + sh_video->vd_driver->uninit(sh_video); #ifdef CONFIG_DYNAMIC_PLUGINS if (sh_video->dec_handle) - dlclose(sh_video->dec_handle); + dlclose(sh_video->dec_handle); #endif vf_uninit_filter_chain(sh_video->vfilter); - sh_video->initialized=0; + sh_video->initialized = 0; } -void vfm_help(void){ +void vfm_help(void) +{ int i; - mp_msg(MSGT_DECVIDEO,MSGL_INFO,MSGTR_AvailableVideoFm); + mp_msg(MSGT_DECVIDEO, MSGL_INFO, MSGTR_AvailableVideoFm); mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_VIDEO_DRIVERS\n"); - mp_msg(MSGT_DECVIDEO,MSGL_INFO," vfm: info: (comment)\n"); - for (i=0; mpcodecs_vd_drivers[i] != NULL; i++) - mp_msg(MSGT_DECVIDEO,MSGL_INFO,"%8s %s (%s)\n", - mpcodecs_vd_drivers[i]->info->short_name, - mpcodecs_vd_drivers[i]->info->name, - mpcodecs_vd_drivers[i]->info->comment); + mp_msg(MSGT_DECVIDEO, MSGL_INFO, " vfm: info: (comment)\n"); + for (i = 0; mpcodecs_vd_drivers[i] != NULL; i++) + mp_msg(MSGT_DECVIDEO, MSGL_INFO, "%8s %s (%s)\n", + mpcodecs_vd_drivers[i]->info->short_name, + mpcodecs_vd_drivers[i]->info->name, + mpcodecs_vd_drivers[i]->info->comment); } -static int init_video(sh_video_t *sh_video,char* codecname,char* vfm,int status, - stringset_t *selected){ +static int init_video(sh_video_t *sh_video, char *codecname, char *vfm, + int status, stringset_t *selected) +{ int force = 0; - unsigned int orig_fourcc=sh_video->bih?sh_video->bih->biCompression:0; - sh_video->codec=NULL; - sh_video->vf_initialized=0; + unsigned int orig_fourcc = + sh_video->bih ? sh_video->bih->biCompression : 0; + sh_video->codec = NULL; + sh_video->vf_initialized = 0; if (codecname && codecname[0] == '+') { - codecname = &codecname[1]; - force = 1; + codecname = &codecname[1]; + force = 1; } - while(1){ - int i; - int orig_w, orig_h; - // restore original fourcc: - if(sh_video->bih) sh_video->bih->biCompression=orig_fourcc; - if(!(sh_video->codec=find_video_codec(sh_video->format, - sh_video->bih?((unsigned int*) &sh_video->bih->biCompression):NULL, - sh_video->codec,force) )) break; - // ok we found one codec - if(stringset_test(selected, sh_video->codec->name)) continue; // already tried & failed - if(codecname && strcmp(sh_video->codec->name,codecname)) continue; // -vc - if(vfm && strcmp(sh_video->codec->drv,vfm)) continue; // vfm doesn't match - if(!force && sh_video->codec->status<status) continue; // too unstable - stringset_add(selected, sh_video->codec->name); // tagging it - // ok, it matches all rules, let's find the driver! - for (i=0; mpcodecs_vd_drivers[i] != NULL; i++) -// if(mpcodecs_vd_drivers[i]->info->id==sh_video->codec->driver) break; - if(!strcmp(mpcodecs_vd_drivers[i]->info->short_name,sh_video->codec->drv)) break; - mpvdec=mpcodecs_vd_drivers[i]; + while (1) { + int i; + int orig_w, orig_h; + // restore original fourcc: + if (sh_video->bih) + sh_video->bih->biCompression = orig_fourcc; + if (! + (sh_video->codec = + find_video_codec(sh_video->format, + sh_video->bih ? ((unsigned int *) &sh_video-> + bih->biCompression) : NULL, + sh_video->codec, force))) + break; + // ok we found one codec + if (stringset_test(selected, sh_video->codec->name)) + continue; // already tried & failed + if (codecname && strcmp(sh_video->codec->name, codecname)) + continue; // -vc + if (vfm && strcmp(sh_video->codec->drv, vfm)) + continue; // vfm doesn't match + if (!force && sh_video->codec->status < status) + continue; // too unstable + stringset_add(selected, sh_video->codec->name); // tagging it + // ok, it matches all rules, let's find the driver! + for (i = 0; mpcodecs_vd_drivers[i] != NULL; i++) + if (!strcmp(mpcodecs_vd_drivers[i]->info->short_name, + sh_video->codec->drv)) + break; + sh_video->vd_driver = mpcodecs_vd_drivers[i]; #ifdef CONFIG_DYNAMIC_PLUGINS - if (!mpvdec) - { - /* try to open shared decoder plugin */ - int buf_len; - char *buf; - vd_functions_t *funcs_sym; - vd_info_t *info_sym; - - buf_len = strlen(MPLAYER_LIBDIR)+strlen(sh_video->codec->drv)+16; - buf = malloc(buf_len); - if (!buf) - break; - snprintf(buf, buf_len, "%s/mplayer/vd_%s.so", MPLAYER_LIBDIR, sh_video->codec->drv); - mp_msg(MSGT_DECVIDEO, MSGL_DBG2, "Trying to open external plugin: %s\n", buf); - sh_video->dec_handle = dlopen(buf, RTLD_LAZY); - if (!sh_video->dec_handle) - break; - snprintf(buf, buf_len, "mpcodecs_vd_%s", sh_video->codec->drv); - funcs_sym = dlsym(sh_video->dec_handle, buf); - if (!funcs_sym || !funcs_sym->info || !funcs_sym->init || - !funcs_sym->uninit || !funcs_sym->control || !funcs_sym->decode) - break; - info_sym = funcs_sym->info; - if (strcmp(info_sym->short_name, sh_video->codec->drv)) - break; - free(buf); - mpvdec = funcs_sym; - mp_msg(MSGT_DECVIDEO, MSGL_V, "Using external decoder plugin (%s/mplayer/vd_%s.so)!\n", - MPLAYER_LIBDIR, sh_video->codec->drv); - } + if (!sh_video->vd_driver) { + /* try to open shared decoder plugin */ + int buf_len; + char *buf; + vd_functions_t *funcs_sym; + vd_info_t *info_sym; + + buf_len = + strlen(MPLAYER_LIBDIR) + strlen(sh_video->codec->drv) + 16; + buf = malloc(buf_len); + if (!buf) + break; + snprintf(buf, buf_len, "%s/mplayer/vd_%s.so", MPLAYER_LIBDIR, + sh_video->codec->drv); + mp_msg(MSGT_DECVIDEO, MSGL_DBG2, + "Trying to open external plugin: %s\n", buf); + sh_video->dec_handle = dlopen(buf, RTLD_LAZY); + if (!sh_video->dec_handle) + break; + snprintf(buf, buf_len, "mpcodecs_vd_%s", sh_video->codec->drv); + funcs_sym = dlsym(sh_video->dec_handle, buf); + if (!funcs_sym || !funcs_sym->info || !funcs_sym->init + || !funcs_sym->uninit || !funcs_sym->control + || !funcs_sym->decode) + break; + info_sym = funcs_sym->info; + if (strcmp(info_sym->short_name, sh_video->codec->drv)) + break; + free(buf); + sh_video->vd_driver = funcs_sym; + mp_msg(MSGT_DECVIDEO, MSGL_V, + "Using external decoder plugin (%s/mplayer/vd_%s.so)!\n", + MPLAYER_LIBDIR, sh_video->codec->drv); + } #endif - if(!mpvdec){ // driver not available (==compiled in) - mp_msg(MSGT_DECVIDEO,MSGL_WARN,MSGTR_VideoCodecFamilyNotAvailableStr, - sh_video->codec->name, sh_video->codec->drv); - continue; - } - orig_w = sh_video->bih ? sh_video->bih->biWidth : sh_video->disp_w; - orig_h = sh_video->bih ? sh_video->bih->biHeight : sh_video->disp_h; - sh_video->disp_w = orig_w; - sh_video->disp_h = orig_h; - // it's available, let's try to init! - if(sh_video->codec->flags & CODECS_FLAG_ALIGN16){ - // align width/height to n*16 - sh_video->disp_w=(sh_video->disp_w+15)&(~15); - sh_video->disp_h=(sh_video->disp_h+15)&(~15); - } - if (sh_video->bih) { - sh_video->bih->biWidth = sh_video->disp_w; - sh_video->bih->biHeight = sh_video->disp_h; - } - // init() - mp_msg(MSGT_DECVIDEO,MSGL_INFO,MSGTR_OpeningVideoDecoder,mpvdec->info->short_name,mpvdec->info->name); - // clear vf init error, it is no longer relevant - if (sh_video->vf_initialized < 0) - sh_video->vf_initialized = 0; - if(!mpvdec->init(sh_video)){ - mp_msg(MSGT_DECVIDEO,MSGL_INFO,MSGTR_VDecoderInitFailed); - sh_video->disp_w=orig_w; - sh_video->disp_h=orig_h; - if (sh_video->bih) { - sh_video->bih->biWidth = sh_video->disp_w; - sh_video->bih->biHeight = sh_video->disp_h; - } - continue; // try next... - } - // Yeah! We got it! - sh_video->initialized=1; - return 1; + if (!sh_video->vd_driver) { // driver not available (==compiled in) + mp_msg(MSGT_DECVIDEO, MSGL_WARN, + MSGTR_VideoCodecFamilyNotAvailableStr, + sh_video->codec->name, sh_video->codec->drv); + continue; + } + orig_w = sh_video->bih ? sh_video->bih->biWidth : sh_video->disp_w; + orig_h = sh_video->bih ? sh_video->bih->biHeight : sh_video->disp_h; + sh_video->disp_w = orig_w; + sh_video->disp_h = orig_h; + // it's available, let's try to init! + if (sh_video->codec->flags & CODECS_FLAG_ALIGN16) { + // align width/height to n*16 + sh_video->disp_w = (sh_video->disp_w + 15) & (~15); + sh_video->disp_h = (sh_video->disp_h + 15) & (~15); + } + if (sh_video->bih) { + sh_video->bih->biWidth = sh_video->disp_w; + sh_video->bih->biHeight = sh_video->disp_h; + } + + // init() + const struct vd_functions *vd = sh_video->vd_driver; + mp_msg(MSGT_DECVIDEO, MSGL_INFO, MSGTR_OpeningVideoDecoder, + vd->info->short_name, vd->info->name); + // clear vf init error, it is no longer relevant + if (sh_video->vf_initialized < 0) + sh_video->vf_initialized = 0; + if (!vd->init(sh_video)) { + mp_msg(MSGT_DECVIDEO, MSGL_INFO, MSGTR_VDecoderInitFailed); + sh_video->disp_w = orig_w; + sh_video->disp_h = orig_h; + if (sh_video->bih) { + sh_video->bih->biWidth = sh_video->disp_w; + sh_video->bih->biHeight = sh_video->disp_h; + } + continue; // try next... + } + // Yeah! We got it! + sh_video->initialized = 1; + return 1; } return 0; } -int init_best_video_codec(sh_video_t *sh_video,char** video_codec_list,char** video_fm_list){ -char* vc_l_default[2]={"",(char*)NULL}; -stringset_t selected; -// hack: -if(!video_codec_list) video_codec_list=vc_l_default; -// Go through the codec.conf and find the best codec... -sh_video->initialized=0; -stringset_init(&selected); -while(!sh_video->initialized && *video_codec_list){ - char* video_codec=*(video_codec_list++); - if(video_codec[0]){ - if(video_codec[0]=='-'){ - // disable this codec: - stringset_add(&selected, video_codec+1); - } else { - // forced codec by name: - mp_msg(MSGT_DECVIDEO,MSGL_INFO,MSGTR_ForcedVideoCodec,video_codec); - init_video(sh_video,video_codec,NULL,-1, &selected); - } - } else { - int status; - // try in stability order: UNTESTED, WORKING, BUGGY. never try CRASHING. - if(video_fm_list){ - char** fmlist=video_fm_list; - // try first the preferred codec families: - while(!sh_video->initialized && *fmlist){ - char* video_fm=*(fmlist++); - mp_msg(MSGT_DECVIDEO,MSGL_INFO,MSGTR_TryForceVideoFmtStr,video_fm); - for(status=CODECS_STATUS__MAX;status>=CODECS_STATUS__MIN;--status) - if(init_video(sh_video,NULL,video_fm,status, &selected)) break; - } +int init_best_video_codec(sh_video_t *sh_video, char **video_codec_list, + char **video_fm_list) +{ + char *vc_l_default[2] = { "", (char *) NULL }; + stringset_t selected; + // hack: + if (!video_codec_list) + video_codec_list = vc_l_default; + // Go through the codec.conf and find the best codec... + sh_video->initialized = 0; + stringset_init(&selected); + while (!sh_video->initialized && *video_codec_list) { + char *video_codec = *(video_codec_list++); + if (video_codec[0]) { + if (video_codec[0] == '-') { + // disable this codec: + stringset_add(&selected, video_codec + 1); + } else { + // forced codec by name: + mp_msg(MSGT_DECVIDEO, MSGL_INFO, MSGTR_ForcedVideoCodec, + video_codec); + init_video(sh_video, video_codec, NULL, -1, &selected); + } + } else { + int status; + // try in stability order: UNTESTED, WORKING, BUGGY. never try CRASHING. + if (video_fm_list) { + char **fmlist = video_fm_list; + // try first the preferred codec families: + while (!sh_video->initialized && *fmlist) { + char *video_fm = *(fmlist++); + mp_msg(MSGT_DECVIDEO, MSGL_INFO, MSGTR_TryForceVideoFmtStr, + video_fm); + for (status = CODECS_STATUS__MAX; + status >= CODECS_STATUS__MIN; --status) + if (init_video + (sh_video, NULL, video_fm, status, &selected)) + break; + } + } + if (!sh_video->initialized) + for (status = CODECS_STATUS__MAX; status >= CODECS_STATUS__MIN; + --status) + if (init_video(sh_video, NULL, NULL, status, &selected)) + break; + } } - if(!sh_video->initialized) - for(status=CODECS_STATUS__MAX;status>=CODECS_STATUS__MIN;--status) - if(init_video(sh_video,NULL,NULL,status, &selected)) break; - } -} -stringset_free(&selected); + stringset_free(&selected); -if(!sh_video->initialized){ - mp_msg(MSGT_DECVIDEO,MSGL_ERR,MSGTR_CantFindVideoCodec,sh_video->format); - mp_msg(MSGT_DECAUDIO,MSGL_HINT, MSGTR_RTFMCodecs); - return 0; // failed -} + if (!sh_video->initialized) { + mp_msg(MSGT_DECVIDEO, MSGL_ERR, MSGTR_CantFindVideoCodec, + sh_video->format); + mp_msg(MSGT_DECAUDIO, MSGL_HINT, MSGTR_RTFMCodecs); + return 0; // failed + } -mp_msg(MSGT_DECVIDEO,MSGL_INFO,MSGTR_SelectedVideoCodec, - sh_video->codec->name,sh_video->codec->drv,sh_video->codec->info); -return 1; // success + mp_msg(MSGT_DECVIDEO, MSGL_INFO, MSGTR_SelectedVideoCodec, + sh_video->codec->name, sh_video->codec->drv, sh_video->codec->info); + return 1; // success } void *decode_video(sh_video_t *sh_video, unsigned char *start, int in_size, - int drop_frame, double pts) + int drop_frame, double pts) { mp_image_t *mpi = NULL; unsigned int t = GetTimer(); unsigned int t2; double tt; + struct MPOpts *opts = sh_video->opts; - if (correct_pts && pts != MP_NOPTS_VALUE) { - int delay = get_current_video_decoder_lag(sh_video); - if (delay >= 0) { - if (delay > sh_video->num_buffered_pts) + if (opts->correct_pts && pts != MP_NOPTS_VALUE) { + int delay = get_current_video_decoder_lag(sh_video); + if (delay >= 0) { + if (delay > sh_video->num_buffered_pts) #if 0 - // this is disabled because vd_ffmpeg reports the same lag - // after seek even when there are no buffered frames, - // leading to incorrect error messages - mp_msg(MSGT_DECVIDEO, MSGL_ERR, "Not enough buffered pts\n"); + // this is disabled because vd_ffmpeg reports the same lag + // after seek even when there are no buffered frames, + // leading to incorrect error messages + mp_msg(MSGT_DECVIDEO, MSGL_ERR, "Not enough buffered pts\n"); #else - ; + ; #endif - else - sh_video->num_buffered_pts = delay; - } - if (sh_video->num_buffered_pts == - sizeof(sh_video->buffered_pts)/sizeof(double)) - mp_msg(MSGT_DECVIDEO, MSGL_ERR, "Too many buffered pts\n"); - else { - int i, j; - for (i = 0; i < sh_video->num_buffered_pts; i++) - if (sh_video->buffered_pts[i] < pts) - break; - for (j = sh_video->num_buffered_pts; j > i; j--) - sh_video->buffered_pts[j] = sh_video->buffered_pts[j-1]; - sh_video->buffered_pts[i] = pts; - sh_video->num_buffered_pts++; - } + else + sh_video->num_buffered_pts = delay; + } + if (sh_video->num_buffered_pts == + sizeof(sh_video->buffered_pts) / sizeof(double)) + mp_msg(MSGT_DECVIDEO, MSGL_ERR, "Too many buffered pts\n"); + else { + int i, j; + for (i = 0; i < sh_video->num_buffered_pts; i++) + if (sh_video->buffered_pts[i] < pts) + break; + for (j = sh_video->num_buffered_pts; j > i; j--) + sh_video->buffered_pts[j] = sh_video->buffered_pts[j - 1]; + sh_video->buffered_pts[i] = pts; + sh_video->num_buffered_pts++; + } } - mpi = mpvdec->decode(sh_video, start, in_size, drop_frame); + mpi = sh_video->vd_driver->decode(sh_video, start, in_size, drop_frame); //------------------------ frame decoded. -------------------- @@ -374,35 +423,34 @@ void *decode_video(sh_video_t *sh_video, unsigned char *start, int in_size, // some codecs are broken, and doesn't restore MMX state :( // it happens usually with broken/damaged files. if (gCpuCaps.has3DNow) { - __asm__ volatile ("femms\n\t":::"memory"); - } - else if (gCpuCaps.hasMMX) { - __asm__ volatile ("emms\n\t":::"memory"); + __asm__ volatile("femms\n\t":::"memory"); + } else if (gCpuCaps.hasMMX) { + __asm__ volatile("emms\n\t":::"memory"); } #endif - t2 = GetTimer(); t = t2-t; - tt = t*0.000001f; + t2 = GetTimer(); + t = t2 - t; + tt = t * 0.000001f; video_time_usage += tt; if (!mpi || drop_frame) - return NULL; // error / skipped frame + return NULL; // error / skipped frame if (field_dominance == 0) - mpi->fields |= MP_IMGFIELD_TOP_FIRST; + mpi->fields |= MP_IMGFIELD_TOP_FIRST; else if (field_dominance == 1) - mpi->fields &= ~MP_IMGFIELD_TOP_FIRST; - - if (correct_pts) { - if (sh_video->num_buffered_pts) { - sh_video->num_buffered_pts--; - sh_video->pts = sh_video->buffered_pts[sh_video->num_buffered_pts]; - } - else { - mp_msg(MSGT_CPLAYER, MSGL_ERR, "No pts value from demuxer to " - "use for frame!\n"); - sh_video->pts = MP_NOPTS_VALUE; - } + mpi->fields &= ~MP_IMGFIELD_TOP_FIRST; + + if (opts->correct_pts) { + if (sh_video->num_buffered_pts) { + sh_video->num_buffered_pts--; + sh_video->pts = sh_video->buffered_pts[sh_video->num_buffered_pts]; + } else { + mp_msg(MSGT_CPLAYER, MSGL_ERR, + "No pts value from demuxer to " "use for frame!\n"); + sh_video->pts = MP_NOPTS_VALUE; + } } return mpi; } @@ -414,15 +462,9 @@ int filter_video(sh_video_t *sh_video, void *frame, double pts) vf_instance_t *vf = sh_video->vfilter; // apply video filters and call the leaf vo/ve int ret = vf->put_image(vf, mpi, pts); - if (ret > 0) { - vf->control(vf, VFCTRL_DRAW_OSD, NULL); -#ifdef CONFIG_ASS - vf->control(vf, VFCTRL_DRAW_EOSD, NULL); -#endif - } - t2 = GetTimer()-t2; - vout_time_usage += t2*0.000001; + t2 = GetTimer() - t2; + vout_time_usage += t2 * 0.000001; return ret; } diff --git a/libmpcodecs/dec_video.h b/libmpcodecs/dec_video.h index 7a08a0410e..606fbe946e 100644 --- a/libmpcodecs/dec_video.h +++ b/libmpcodecs/dec_video.h @@ -3,6 +3,8 @@ #include "libmpdemux/stheader.h" +struct osd_state; + // dec_video.c: void vfm_help(void); @@ -18,6 +20,7 @@ void set_video_quality(sh_video_t *sh_video, int quality); int get_video_colors(sh_video_t *sh_video, const char *item, int *value); int set_video_colors(sh_video_t *sh_video, const char *item, int value); int set_rectangle(sh_video_t *sh_video, int param, int value); +int redraw_osd(struct sh_video *sh_video, struct osd_state *osd); void resync_video_stream(sh_video_t *sh_video); int get_current_video_decoder_lag(sh_video_t *sh_video); diff --git a/libmpcodecs/mp_image.h b/libmpcodecs/mp_image.h index 7d82707d10..fb06e62fc9 100644 --- a/libmpcodecs/mp_image.h +++ b/libmpcodecs/mp_image.h @@ -80,7 +80,7 @@ #define MP_IMGFIELD_BOTTOM 0x10 #define MP_IMGFIELD_INTERLACED 0x20 -typedef struct mp_image_s { +typedef struct mp_image { unsigned int flags; unsigned char type; int number; diff --git a/libmpcodecs/native/rtjpegn.c b/libmpcodecs/native/rtjpegn.c index 538bff609a..b97e507817 100644 --- a/libmpcodecs/native/rtjpegn.c +++ b/libmpcodecs/native/rtjpegn.c @@ -133,7 +133,7 @@ static const unsigned char RTjpeg_chrom_quant_tbl[64] = { /* Block to Stream (encoding) */ /* */ -int RTjpeg_b2s(__s16 *data, __s8 *strm, __u8 bt8) +static int RTjpeg_b2s(__s16 *data, __s8 *strm, __u8 bt8) { register int ci, co=1; register __s16 ZZvalue; @@ -303,7 +303,7 @@ fprintf(stdout, "\n\n"); /* Stream to Block (decoding) */ /* */ -int RTjpeg_s2b(__s16 *data, __s8 *strm, __u8 bt8, __u32 *qtbl) +static int RTjpeg_s2b(__s16 *data, __s8 *strm, __u8 bt8, __u32 *qtbl) { int ci; register int co; @@ -447,7 +447,7 @@ fprintf(stdout, "\n\n"); #else -int RTjpeg_b2s(__s16 *data, __s8 *strm, __u8 bt8) +static int RTjpeg_b2s(__s16 *data, __s8 *strm, __u8 bt8) { register int ci, co=1, tmp; register __s16 ZZvalue; @@ -506,7 +506,7 @@ int RTjpeg_b2s(__s16 *data, __s8 *strm, __u8 bt8) return (int)co; } -int RTjpeg_s2b(__s16 *data, __s8 *strm, __u8 bt8, __u32 *qtbl) +static int RTjpeg_s2b(__s16 *data, __s8 *strm, __u8 bt8, __u32 *qtbl) { int ci=1, co=1, tmp; register int i; @@ -539,7 +539,7 @@ int RTjpeg_s2b(__s16 *data, __s8 *strm, __u8 bt8, __u32 *qtbl) #endif #if HAVE_MMX -void RTjpeg_quant_init(void) +static void RTjpeg_quant_init(void) { int i; __s16 *qtbl; @@ -554,7 +554,7 @@ void RTjpeg_quant_init(void) static mmx_t RTjpeg_ones={0x0001000100010001LL}; static mmx_t RTjpeg_half={0x7fff7fff7fff7fffLL}; -void RTjpeg_quant(__s16 *block, __s32 *qtbl) +static void RTjpeg_quant(__s16 *block, __s32 *qtbl) { int i; mmx_t *bl, *ql; @@ -591,11 +591,11 @@ void RTjpeg_quant(__s16 *block, __s32 *qtbl) } } #else -void RTjpeg_quant_init(void) +static void RTjpeg_quant_init(void) { } -void RTjpeg_quant(__s16 *block, __s32 *qtbl) +static void RTjpeg_quant(__s16 *block, __s32 *qtbl) { int i; @@ -626,7 +626,7 @@ static mmx_t RTjpeg_zero ={0x0000000000000000LL}; #define D_MULTIPLY(var,const) ((__s32) ((var) * (const))) #endif -void RTjpeg_dct_init(void) +static void RTjpeg_dct_init(void) { int i; @@ -637,7 +637,7 @@ void RTjpeg_dct_init(void) } } -void RTjpeg_dctY(__u8 *idata, __s16 *odata, int rskip) +static void RTjpeg_dctY(__u8 *idata, __s16 *odata, int rskip) { #if !HAVE_MMX __s32 tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; @@ -1554,7 +1554,7 @@ void RTjpeg_dctY(__u8 *idata, __s16 *odata, int rskip) #define RL(x) ((x)>235) ? 235 : (((x)<16) ? 16 : (x)) #define MULTIPLY(var,const) (((__s32) ((var) * (const)) + 128)>>8) -void RTjpeg_idct_init(void) +static void RTjpeg_idct_init(void) { int i; @@ -1565,7 +1565,7 @@ void RTjpeg_idct_init(void) } } -void RTjpeg_idct(__u8 *odata, __s16 *data, int rskip) +static void RTjpeg_idct(__u8 *odata, __s16 *data, int rskip) { #if HAVE_MMX @@ -2702,7 +2702,7 @@ Initialise all the cache-aliged data blocks */ -void RTjpeg_init_data(void) +static void RTjpeg_init_data(void) { unsigned long dptr; @@ -3140,7 +3140,7 @@ void RTjpeg_init_mcompress(void) #if HAVE_MMX -int RTjpeg_bcomp(__s16 *old, mmx_t *mask) +static int RTjpeg_bcomp(__s16 *old, mmx_t *mask) { int i; mmx_t *mold=(mmx_t *)old; @@ -3186,7 +3186,7 @@ int RTjpeg_bcomp(__s16 *old, mmx_t *mask) } #else -int RTjpeg_bcomp(__s16 *old, __u16 *mask) +static int RTjpeg_bcomp(__s16 *old, __u16 *mask) { int i; @@ -3412,10 +3412,6 @@ int RTjpeg_mcompress8(__s8 *sp, unsigned char *bp, __u16 lmask) return (sp-sb); } -void RTjpeg_color_init(void) -{ -} - #define KcrR 76284 #define KcrG 53281 #define KcbG 25625 diff --git a/libmpcodecs/native/xa_gsm.c b/libmpcodecs/native/xa_gsm.c index 546edf81dc..86cedeb48b 100644 --- a/libmpcodecs/native/xa_gsm.c +++ b/libmpcodecs/native/xa_gsm.c @@ -258,7 +258,7 @@ register word * s; } /**** 4.3.2 */ -void Gsm_Long_Term_Synthesis_Filtering (S,Ncr,bcr,erp,drp) +static void Gsm_Long_Term_Synthesis_Filtering (S,Ncr,bcr,erp,drp) XA_GSM_STATE * S; word Ncr; word bcr; diff --git a/libmpcodecs/vd.c b/libmpcodecs/vd.c index 67f6b3e7e0..86b9f0c511 100644 --- a/libmpcodecs/vd.c +++ b/libmpcodecs/vd.c @@ -5,13 +5,9 @@ #include "config.h" #include "mp_msg.h" #include "help_mp.h" - -#ifdef HAVE_MALLOC_H -#include <malloc.h> -#endif +#include "options.h" #include "codec-cfg.h" -//#include "mp_image.h" #include "img_format.h" @@ -23,314 +19,309 @@ #include "vd.h" #include "vf.h" -//#include "vd_internal.h" - -extern vd_functions_t mpcodecs_vd_null; -extern vd_functions_t mpcodecs_vd_ffmpeg; -extern vd_functions_t mpcodecs_vd_theora; -extern vd_functions_t mpcodecs_vd_dshow; -extern vd_functions_t mpcodecs_vd_dmo; -extern vd_functions_t mpcodecs_vd_vfw; -extern vd_functions_t mpcodecs_vd_vfwex; -extern vd_functions_t mpcodecs_vd_raw; -extern vd_functions_t mpcodecs_vd_hmblck; -extern vd_functions_t mpcodecs_vd_xanim; -extern vd_functions_t mpcodecs_vd_nuv; -extern vd_functions_t mpcodecs_vd_mpng; -extern vd_functions_t mpcodecs_vd_ijpg; -extern vd_functions_t mpcodecs_vd_mtga; -extern vd_functions_t mpcodecs_vd_sgi; -extern vd_functions_t mpcodecs_vd_libmpeg2; -extern vd_functions_t mpcodecs_vd_mpegpes; -extern vd_functions_t mpcodecs_vd_zrmjpeg; -extern vd_functions_t mpcodecs_vd_realvid; -extern vd_functions_t mpcodecs_vd_xvid; -extern vd_functions_t mpcodecs_vd_libdv; -extern vd_functions_t mpcodecs_vd_lzo; -extern vd_functions_t mpcodecs_vd_qtvideo; +extern const vd_functions_t mpcodecs_vd_null; +extern const vd_functions_t mpcodecs_vd_ffmpeg; +extern const vd_functions_t mpcodecs_vd_theora; +extern const vd_functions_t mpcodecs_vd_dshow; +extern const vd_functions_t mpcodecs_vd_dmo; +extern const vd_functions_t mpcodecs_vd_vfw; +extern const vd_functions_t mpcodecs_vd_vfwex; +extern const vd_functions_t mpcodecs_vd_raw; +extern const vd_functions_t mpcodecs_vd_hmblck; +extern const vd_functions_t mpcodecs_vd_xanim; +extern const vd_functions_t mpcodecs_vd_nuv; +extern const vd_functions_t mpcodecs_vd_mpng; +extern const vd_functions_t mpcodecs_vd_ijpg; +extern const vd_functions_t mpcodecs_vd_mtga; +extern const vd_functions_t mpcodecs_vd_sgi; +extern const vd_functions_t mpcodecs_vd_libmpeg2; +extern const vd_functions_t mpcodecs_vd_mpegpes; +extern const vd_functions_t mpcodecs_vd_zrmjpeg; +extern const vd_functions_t mpcodecs_vd_realvid; +extern const vd_functions_t mpcodecs_vd_xvid; +extern const vd_functions_t mpcodecs_vd_libdv; +extern const vd_functions_t mpcodecs_vd_lzo; +extern const vd_functions_t mpcodecs_vd_qtvideo; /* Please do not add any new decoders here. If you want to implement a new * decoder, add it to libavcodec, except for wrappers around external * libraries and decoders requiring binary support. */ -vd_functions_t* mpcodecs_vd_drivers[] = { - &mpcodecs_vd_null, +const vd_functions_t * const mpcodecs_vd_drivers[] = { + &mpcodecs_vd_null, #ifdef CONFIG_LIBAVCODEC - &mpcodecs_vd_ffmpeg, + &mpcodecs_vd_ffmpeg, #endif #ifdef CONFIG_OGGTHEORA - &mpcodecs_vd_theora, + &mpcodecs_vd_theora, #endif #ifdef CONFIG_WIN32DLL - &mpcodecs_vd_dshow, - &mpcodecs_vd_dmo, - &mpcodecs_vd_vfw, - &mpcodecs_vd_vfwex, + &mpcodecs_vd_dshow, + &mpcodecs_vd_dmo, + &mpcodecs_vd_vfw, + &mpcodecs_vd_vfwex, #endif - &mpcodecs_vd_lzo, - &mpcodecs_vd_raw, - &mpcodecs_vd_hmblck, - &mpcodecs_vd_nuv, + &mpcodecs_vd_lzo, + &mpcodecs_vd_raw, + &mpcodecs_vd_hmblck, + &mpcodecs_vd_nuv, #ifdef CONFIG_XANIM - &mpcodecs_vd_xanim, + &mpcodecs_vd_xanim, #endif #ifdef CONFIG_PNG - &mpcodecs_vd_mpng, + &mpcodecs_vd_mpng, #endif #ifdef CONFIG_JPEG - &mpcodecs_vd_ijpg, + &mpcodecs_vd_ijpg, #endif - &mpcodecs_vd_mtga, - &mpcodecs_vd_sgi, + &mpcodecs_vd_mtga, + &mpcodecs_vd_sgi, #ifdef CONFIG_LIBMPEG2 - &mpcodecs_vd_libmpeg2, + &mpcodecs_vd_libmpeg2, #endif - &mpcodecs_vd_mpegpes, + &mpcodecs_vd_mpegpes, #ifdef CONFIG_ZR - &mpcodecs_vd_zrmjpeg, + &mpcodecs_vd_zrmjpeg, #endif #ifdef CONFIG_REALCODECS - &mpcodecs_vd_realvid, + &mpcodecs_vd_realvid, #endif #ifdef CONFIG_XVID4 - &mpcodecs_vd_xvid, + &mpcodecs_vd_xvid, #endif #ifdef CONFIG_LIBDV095 - &mpcodecs_vd_libdv, + &mpcodecs_vd_libdv, #endif #ifdef CONFIG_QTX_CODECS - &mpcodecs_vd_qtvideo, + &mpcodecs_vd_qtvideo, #endif /* Please do not add any new decoders here. If you want to implement a new * decoder, add it to libavcodec, except for wrappers around external * libraries and decoders requiring binary support. */ - NULL + NULL }; #include "libvo/video_out.h" -// libvo opts: -int fullscreen=0; -int vidmode=0; -int softzoom=0; -int flip=-1; -int opt_screen_size_x=0; -int opt_screen_size_y=0; -float screen_size_xy=0; -float movie_aspect=-1.0; -int vo_flags=0; -int vd_use_slices=1; - -/** global variables for gamma, brightness, contrast, saturation and hue - modified by mplayer.c and gui/mplayer/gtk/eq.c: - ranges -100 - 100 - 1000 if the vo default should be used -*/ -int vo_gamma_gamma = 1000; -int vo_gamma_brightness = 1000; -int vo_gamma_contrast = 1000; -int vo_gamma_saturation = 1000; -int vo_gamma_hue = 1000; - -extern vd_functions_t* mpvdec; // FIXME! - -#define SCREEN_SIZE_X 1 -#define SCREEN_SIZE_Y 1 - -int mpcodecs_config_vo(sh_video_t *sh, int w, int h, unsigned int preferred_outfmt){ - int i,j; - unsigned int out_fmt=0; - int screen_size_x=0;//SCREEN_SIZE_X; - int screen_size_y=0;//SCREEN_SIZE_Y; - vf_instance_t* vf=sh->vfilter,*sc=NULL; - int palette=0; - int vocfg_flags=0; - - if(w) - sh->disp_w=w; - if(h) - sh->disp_h=h; - - if(!sh->disp_w || !sh->disp_h) - return 0; - - mp_msg(MSGT_DECVIDEO,MSGL_INFO,MSGTR_VoConfigRequest,w,h,vo_format_name(preferred_outfmt)); - -// if(!vf) return 1; // temp hack - - if(get_video_quality_max(sh)<=0 && divx_quality){ - // user wants postprocess but no pp filter yet: - sh->vfilter=vf=vf_open_filter(vf,"pp",NULL); +int mpcodecs_config_vo(sh_video_t *sh, int w, int h, + unsigned int preferred_outfmt) +{ + struct MPOpts *opts = sh->opts; + int i, j; + unsigned int out_fmt = 0; + int screen_size_x = 0; + int screen_size_y = 0; + vf_instance_t *vf = sh->vfilter, *sc = NULL; + int palette = 0; + int vocfg_flags = 0; + + if (w) + sh->disp_w = w; + if (h) + sh->disp_h = h; + + if (!sh->disp_w || !sh->disp_h) + return 0; + + mp_msg(MSGT_DECVIDEO, MSGL_INFO, MSGTR_VoConfigRequest, w, h, + vo_format_name(preferred_outfmt)); + + if (get_video_quality_max(sh) <= 0 && divx_quality) { + // user wants postprocess but no pp filter yet: + sh->vfilter = vf = vf_open_filter(opts, vf, "pp", NULL); } - // check if libvo and codec has common outfmt (no conversion): -csp_again: - - if( mp_msg_test(MSGT_DECVIDEO,MSGL_V) ){ - vf_instance_t* f=vf; - mp_msg(MSGT_DECVIDEO,MSGL_V,"Trying filter chain:"); - for(f = vf ; f ; f = f->next) - mp_msg(MSGT_DECVIDEO,MSGL_V," %s",f->info->name); - mp_msg(MSGT_DECVIDEO,MSGL_V,"\n"); + csp_again: + + if (mp_msg_test(MSGT_DECVIDEO, MSGL_V)) { + vf_instance_t *f = vf; + mp_msg(MSGT_DECVIDEO, MSGL_V, "Trying filter chain:"); + for (f = vf; f; f = f->next) + mp_msg(MSGT_DECVIDEO, MSGL_V, " %s", f->info->name); + mp_msg(MSGT_DECVIDEO, MSGL_V, "\n"); } - j=-1; - for(i=0;i<CODECS_MAX_OUTFMT;i++){ - int flags; - out_fmt=sh->codec->outfmt[i]; - if(out_fmt==(unsigned int)0xFFFFFFFF) continue; - flags=vf->query_format(vf,out_fmt); - mp_msg(MSGT_CPLAYER,MSGL_DBG2,"vo_debug: query(%s) returned 0x%X (i=%d) \n",vo_format_name(out_fmt),flags,i); - if((flags&VFCAP_CSP_SUPPORTED_BY_HW) || (flags&VFCAP_CSP_SUPPORTED && j<0)){ - // check (query) if codec really support this outfmt... - sh->outfmtidx=j; // pass index to the control() function this way - if(mpvdec->control(sh,VDCTRL_QUERY_FORMAT,&out_fmt)==CONTROL_FALSE){ - mp_msg(MSGT_CPLAYER,MSGL_DBG2,"vo_debug: codec query_format(%s) returned FALSE\n",vo_format_name(out_fmt)); - continue; - } - j=i; vo_flags=flags; if(flags&VFCAP_CSP_SUPPORTED_BY_HW) break; - } else - if(!palette && !(flags&(VFCAP_CSP_SUPPORTED_BY_HW|VFCAP_CSP_SUPPORTED)) && (out_fmt==IMGFMT_RGB8||out_fmt==IMGFMT_BGR8)){ - sh->outfmtidx=j; // pass index to the control() function this way - if(mpvdec->control(sh,VDCTRL_QUERY_FORMAT,&out_fmt)!=CONTROL_FALSE) - palette=1; - } + j = -1; + for (i = 0; i < CODECS_MAX_OUTFMT; i++) { + int flags; + out_fmt = sh->codec->outfmt[i]; + if (out_fmt == (unsigned int) 0xFFFFFFFF) + continue; + flags = vf->query_format(vf, out_fmt); + mp_msg(MSGT_CPLAYER, MSGL_DBG2, + "vo_debug: query(%s) returned 0x%X (i=%d) \n", + vo_format_name(out_fmt), flags, i); + if ((flags & VFCAP_CSP_SUPPORTED_BY_HW) + || (flags & VFCAP_CSP_SUPPORTED && j < 0)) { + // check (query) if codec really support this outfmt... + sh->outfmtidx = j; // pass index to the control() function this way + if (sh->vd_driver->control(sh, VDCTRL_QUERY_FORMAT, &out_fmt) == + CONTROL_FALSE) { + mp_msg(MSGT_CPLAYER, MSGL_DBG2, + "vo_debug: codec query_format(%s) returned FALSE\n", + vo_format_name(out_fmt)); + continue; + } + j = i; + sh->output_flags = flags; + if (flags & VFCAP_CSP_SUPPORTED_BY_HW) + break; + } else if (!palette + && !(flags & + (VFCAP_CSP_SUPPORTED_BY_HW | VFCAP_CSP_SUPPORTED)) + && (out_fmt == IMGFMT_RGB8 || out_fmt == IMGFMT_BGR8)) { + sh->outfmtidx = j; // pass index to the control() function this way + if (sh->vd_driver->control(sh, VDCTRL_QUERY_FORMAT, &out_fmt) != + CONTROL_FALSE) + palette = 1; + } } - if(j<0){ - // TODO: no match - we should use conversion... - if(strcmp(vf->info->name,"scale") && palette!=-1){ - mp_msg(MSGT_DECVIDEO,MSGL_INFO,MSGTR_CouldNotFindColorspace); - sc=vf=vf_open_filter(vf,"scale",NULL); - goto csp_again; - } else - if(palette==1){ - mp_msg(MSGT_DECVIDEO,MSGL_V,"vd: Trying -vf palette...\n"); - palette=-1; - vf=vf_open_filter(vf,"palette",NULL); - goto csp_again; - } else - { // sws failed, if the last filter (vf_vo) support MPEGPES try to append vf_lavc - vf_instance_t* vo, *vp = NULL, *ve; - // Remove the scale filter if we added it ourself - if(vf == sc) { - ve = vf; - vf = vf->next; - vf_uninit_filter(ve); - } - // Find the last filter (vf_vo) - for(vo = vf ; vo->next ; vo = vo->next) - vp = vo; - if(vo->query_format(vo,IMGFMT_MPEGPES) && (!vp || (vp && strcmp(vp->info->name,"lavc")))) { - ve = vf_open_filter(vo,"lavc",NULL); - if(vp) vp->next = ve; - else vf = ve; - goto csp_again; - } - } - mp_msg(MSGT_CPLAYER,MSGL_WARN,MSGTR_VOincompCodec); - sh->vf_initialized=-1; - return 0; // failed + if (j < 0) { + // TODO: no match - we should use conversion... + if (strcmp(vf->info->name, "scale") && palette != -1) { + mp_msg(MSGT_DECVIDEO, MSGL_INFO, MSGTR_CouldNotFindColorspace); + sc = vf = vf_open_filter(opts, vf, "scale", NULL); + goto csp_again; + } else if (palette == 1) { + mp_msg(MSGT_DECVIDEO, MSGL_V, "vd: Trying -vf palette...\n"); + palette = -1; + vf = vf_open_filter(opts, vf, "palette", NULL); + goto csp_again; + } else { + // sws failed, if the last filter (vf_vo) support MPEGPES try + // to append vf_lavc + vf_instance_t *vo, *vp = NULL, *ve; + // Remove the scale filter if we added it ourselves + if (vf == sc) { + ve = vf; + vf = vf->next; + vf_uninit_filter(ve); + } + // Find the last filter (vf_vo) + for (vo = vf; vo->next; vo = vo->next) + vp = vo; + if (vo->query_format(vo, IMGFMT_MPEGPES) + && (!vp || (vp && strcmp(vp->info->name, "lavc")))) { + ve = vf_open_filter(opts, vo, "lavc", NULL); + if (vp) + vp->next = ve; + else + vf = ve; + goto csp_again; + } + } + mp_msg(MSGT_CPLAYER, MSGL_WARN, MSGTR_VOincompCodec); + sh->vf_initialized = -1; + return 0; // failed } - out_fmt=sh->codec->outfmt[j]; - mp_msg(MSGT_CPLAYER,MSGL_INFO,MSGTR_UsingXAsOutputCspNoY,vo_format_name(out_fmt),j); - sh->outfmtidx=j; - sh->vfilter=vf; + out_fmt = sh->codec->outfmt[j]; + mp_msg(MSGT_CPLAYER, MSGL_INFO, MSGTR_UsingXAsOutputCspNoY, + vo_format_name(out_fmt), j); + sh->outfmtidx = j; + sh->vfilter = vf; // autodetect flipping - if(flip==-1){ - flip=0; - if(sh->codec->outflags[j]&CODECS_FLAG_FLIP) - if(!(sh->codec->outflags[j]&CODECS_FLAG_NOFLIP)) - flip=1; + if (opts->flip == -1) { + opts->flip = 0; + if (sh->codec->outflags[j] & CODECS_FLAG_FLIP) + if (!(sh->codec->outflags[j] & CODECS_FLAG_NOFLIP)) + opts->flip = 1; } - if(vo_flags&VFCAP_FLIPPED) flip^=1; - if(flip && !(vo_flags&VFCAP_FLIP)){ - // we need to flip, but no flipping filter avail. - vf_add_before_vo(&vf, "flip", NULL); - sh->vfilter = vf; + if (sh->output_flags & VFCAP_FLIPPED) + opts->flip ^= 1; + if (opts->flip && !(sh->output_flags & VFCAP_FLIP)) { + // we need to flip, but no flipping filter avail. + vf_add_before_vo(&vf, "flip", NULL); + sh->vfilter = vf; } - // time to do aspect ratio corrections... - if(movie_aspect>-1.0) sh->aspect = movie_aspect; // cmdline overrides autodetect - else if(sh->stream_aspect!=0.0) sh->aspect = sh->stream_aspect; -// if(!sh->aspect) sh->aspect=1.0; - - if(opt_screen_size_x||opt_screen_size_y){ - screen_size_x = opt_screen_size_x; - screen_size_y = opt_screen_size_y; - if(!vidmode){ - if(!screen_size_x) screen_size_x=SCREEN_SIZE_X; - if(!screen_size_y) screen_size_y=SCREEN_SIZE_Y; - if(screen_size_x<=8) screen_size_x*=sh->disp_w; - if(screen_size_y<=8) screen_size_y*=sh->disp_h; - } - } else { - // check source format aspect, calculate prescale ::atmos - screen_size_x=sh->disp_w; - screen_size_y=sh->disp_h; - if(screen_size_xy>=0.001){ - if(screen_size_xy<=8){ - // -xy means x+y scale - screen_size_x*=screen_size_xy; - screen_size_y*=screen_size_xy; - } else { - // -xy means forced width while keeping correct aspect - screen_size_x=screen_size_xy; - screen_size_y=screen_size_xy*sh->disp_h/sh->disp_w; - } - } - if(sh->aspect>0.01){ - int w; - mp_msg(MSGT_CPLAYER,MSGL_INFO,MSGTR_MovieAspectIsSet,sh->aspect); - mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_VIDEO_ASPECT=%1.4f\n", sh->aspect); - w=(int)((float)screen_size_y*sh->aspect); w+=w%2; // round - // we don't like horizontal downscale || user forced width: - if(w<screen_size_x || screen_size_xy>8){ - screen_size_y=(int)((float)screen_size_x*(1.0/sh->aspect)); - screen_size_y+=screen_size_y%2; // round - } else screen_size_x=w; // keep new width + if (opts->movie_aspect > -1.0) + sh->aspect = opts->movie_aspect; // cmdline overrides autodetect + else if (sh->stream_aspect != 0.0) + sh->aspect = sh->stream_aspect; + + if (opts->screen_size_x || opts->screen_size_y) { + screen_size_x = opts->screen_size_x; + screen_size_y = opts->screen_size_y; + if (!opts->vidmode) { + if (!screen_size_x) + screen_size_x = 1; + if (!screen_size_y) + screen_size_y = 1; + if (screen_size_x <= 8) + screen_size_x *= sh->disp_w; + if (screen_size_y <= 8) + screen_size_y *= sh->disp_h; + } } else { - mp_msg(MSGT_CPLAYER,MSGL_INFO,MSGTR_MovieAspectUndefined); + // check source format aspect, calculate prescale ::atmos + screen_size_x = sh->disp_w; + screen_size_y = sh->disp_h; + if (opts->screen_size_xy >= 0.001) { + if (opts->screen_size_xy <= 8) { + // -xy means x+y scale + screen_size_x *= opts->screen_size_xy; + screen_size_y *= opts->screen_size_xy; + } else { + // -xy means forced width while keeping correct aspect + screen_size_x = opts->screen_size_xy; + screen_size_y = opts->screen_size_xy * sh->disp_h / sh->disp_w; + } + } + if (sh->aspect > 0.01) { + int w; + mp_msg(MSGT_CPLAYER, MSGL_INFO, MSGTR_MovieAspectIsSet, + sh->aspect); + mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_VIDEO_ASPECT=%1.4f\n", + sh->aspect); + w = (int) ((float) screen_size_y * sh->aspect); + w += w % 2; // round + // we don't like horizontal downscale || user forced width: + if (w < screen_size_x || opts->screen_size_xy > 8) { + screen_size_y = + (int) ((float) screen_size_x * (1.0 / sh->aspect)); + screen_size_y += screen_size_y % 2; // round + } else + screen_size_x = w; // keep new width + } else { + mp_msg(MSGT_CPLAYER, MSGL_INFO, MSGTR_MovieAspectUndefined); + } } - } - vocfg_flags = (fullscreen ? VOFLAG_FULLSCREEN:0) - | (vidmode ? VOFLAG_MODESWITCHING:0) - | (softzoom ? VOFLAG_SWSCALE:0) - | (flip ? VOFLAG_FLIPPING:0); + vocfg_flags = (opts->fullscreen ? VOFLAG_FULLSCREEN : 0) + | (opts->vidmode ? VOFLAG_MODESWITCHING : 0) + | (opts->softzoom ? VOFLAG_SWSCALE : 0) + | (opts->flip ? VOFLAG_FLIPPING : 0); // Time to config libvo! - mp_msg(MSGT_CPLAYER,MSGL_V,"VO Config (%dx%d->%dx%d,flags=%d,'%s',0x%X)\n", - sh->disp_w,sh->disp_h, - screen_size_x,screen_size_y, - vocfg_flags, - "MPlayer",out_fmt); + mp_msg(MSGT_CPLAYER, MSGL_V, + "VO Config (%dx%d->%dx%d,flags=%d,'%s',0x%X)\n", sh->disp_w, + sh->disp_h, screen_size_x, screen_size_y, vocfg_flags, "MPlayer", + out_fmt); vf->w = sh->disp_w; vf->h = sh->disp_h; - if(vf_config_wrapper(vf,sh->disp_w,sh->disp_h, - screen_size_x,screen_size_y, - vocfg_flags, - out_fmt)==0){ -// "MPlayer",out_fmt)){ - mp_msg(MSGT_CPLAYER,MSGL_WARN,MSGTR_CannotInitVO); - sh->vf_initialized=-1; - return 0; + if (vf_config_wrapper + (vf, sh->disp_w, sh->disp_h, screen_size_x, screen_size_y, vocfg_flags, + out_fmt) == 0) { + mp_msg(MSGT_CPLAYER, MSGL_WARN, MSGTR_CannotInitVO); + sh->vf_initialized = -1; + return 0; } - sh->vf_initialized=1; + sh->vf_initialized = 1; - if (vo_gamma_gamma != 1000) - set_video_colors(sh, "gamma", vo_gamma_gamma); - if (vo_gamma_brightness != 1000) - set_video_colors(sh, "brightness", vo_gamma_brightness); - if (vo_gamma_contrast != 1000) - set_video_colors(sh, "contrast", vo_gamma_contrast); - if (vo_gamma_saturation != 1000) - set_video_colors(sh, "saturation", vo_gamma_saturation); - if (vo_gamma_hue != 1000) - set_video_colors(sh, "hue", vo_gamma_hue); + if (opts->vo_gamma_gamma != 1000) + set_video_colors(sh, "gamma", opts->vo_gamma_gamma); + if (opts->vo_gamma_brightness != 1000) + set_video_colors(sh, "brightness", opts->vo_gamma_brightness); + if (opts->vo_gamma_contrast != 1000) + set_video_colors(sh, "contrast", opts->vo_gamma_contrast); + if (opts->vo_gamma_saturation != 1000) + set_video_colors(sh, "saturation", opts->vo_gamma_saturation); + if (opts->vo_gamma_hue != 1000) + set_video_colors(sh, "hue", opts->vo_gamma_hue); return 1; } @@ -339,15 +330,21 @@ csp_again: // mp_imgflag: buffer requirements (read/write, preserve, stride limits), see mp_image.h // returns NULL or allocated mp_image_t* // Note: buffer allocation may be moved to mpcodecs_config_vo() later... -mp_image_t* mpcodecs_get_image(sh_video_t *sh, int mp_imgtype, int mp_imgflag, int w, int h){ - mp_image_t* mpi=vf_get_image(sh->vfilter,sh->codec->outfmt[sh->outfmtidx],mp_imgtype,mp_imgflag,w,h); - mpi->x=mpi->y=0; - return mpi; +mp_image_t *mpcodecs_get_image(sh_video_t *sh, int mp_imgtype, int mp_imgflag, + int w, int h) +{ + mp_image_t *mpi = + vf_get_image(sh->vfilter, sh->codec->outfmt[sh->outfmtidx], mp_imgtype, + mp_imgflag, w, h); + mpi->x = mpi->y = 0; + return mpi; } -void mpcodecs_draw_slice(sh_video_t *sh, unsigned char** src, int* stride, int w,int h, int x, int y) { - struct vf_instance_s* vf = sh->vfilter; +void mpcodecs_draw_slice(sh_video_t *sh, unsigned char **src, int *stride, + int w, int h, int x, int y) +{ + struct vf_instance *vf = sh->vfilter; - if(vf->draw_slice) - vf->draw_slice(vf,src,stride,w,h,x,y); + if (vf->draw_slice) + vf->draw_slice(vf, src, stride, w, h, x, y); } diff --git a/libmpcodecs/vd.h b/libmpcodecs/vd.h index a3d77339c4..df71970f7d 100644 --- a/libmpcodecs/vd.h +++ b/libmpcodecs/vd.h @@ -8,9 +8,9 @@ typedef mp_codec_info_t vd_info_t; /* interface of video decoder drivers */ -typedef struct vd_functions_s +typedef struct vd_functions { - vd_info_t *info; + const vd_info_t *info; int (*init)(sh_video_t *sh); void (*uninit)(sh_video_t *sh); int (*control)(sh_video_t *sh,int cmd,void* arg, ...); @@ -18,9 +18,7 @@ typedef struct vd_functions_s } vd_functions_t; // NULL terminated array of all drivers -extern vd_functions_t* mpcodecs_vd_drivers[]; - -extern int vd_use_slices; +extern const vd_functions_t * const mpcodecs_vd_drivers[]; #define VDCTRL_QUERY_FORMAT 3 /* test for availabilty of a format */ #define VDCTRL_QUERY_MAX_PP_LEVEL 4 /* test for postprocessing support (max level) */ diff --git a/libmpcodecs/vd_dmo.c b/libmpcodecs/vd_dmo.c index 22682675ca..abce6a9da6 100644 --- a/libmpcodecs/vd_dmo.c +++ b/libmpcodecs/vd_dmo.c @@ -11,7 +11,7 @@ #include "loader/dmo/DMO_VideoDecoder.h" -static vd_info_t info = { +static const vd_info_t info = { "DMO video codecs", "dmo", "A'rpi", diff --git a/libmpcodecs/vd_dshow.c b/libmpcodecs/vd_dshow.c index 391c59fe94..febdbb4e3f 100644 --- a/libmpcodecs/vd_dshow.c +++ b/libmpcodecs/vd_dshow.c @@ -11,7 +11,7 @@ #include "loader/dshow/DS_VideoDecoder.h" -static vd_info_t info = { +static const vd_info_t info = { "DirectShow video codecs", "dshow", "A'rpi", diff --git a/libmpcodecs/vd_ffmpeg.c b/libmpcodecs/vd_ffmpeg.c index c026ccfc37..9e3aae2d08 100644 --- a/libmpcodecs/vd_ffmpeg.c +++ b/libmpcodecs/vd_ffmpeg.c @@ -6,6 +6,7 @@ #include "config.h" #include "mp_msg.h" #include "help_mp.h" +#include "options.h" #include "av_opts.h" #include "libavutil/common.h" @@ -15,7 +16,7 @@ #include "vd_internal.h" -static vd_info_t info = { +static const vd_info_t info = { "FFmpeg's libavcodec codec family", "ffmpeg", "A'rpi", @@ -49,57 +50,38 @@ typedef struct { int ip_count; int b_count; AVRational last_sample_aspect_ratio; + int lowres; } vd_ffmpeg_ctx; #include "m_option.h" static int get_buffer(AVCodecContext *avctx, AVFrame *pic); static void release_buffer(AVCodecContext *avctx, AVFrame *pic); -static void draw_slice(struct AVCodecContext *s, AVFrame *src, int offset[4], - int y, int type, int height); +static void draw_slice(struct AVCodecContext *s, const AVFrame *src, + int offset[4], int y, int type, int height); static enum PixelFormat get_format(struct AVCodecContext *avctx, const enum PixelFormat *pix_fmt); -static int lavc_param_workaround_bugs= FF_BUG_AUTODETECT; -static int lavc_param_error_resilience=2; -static int lavc_param_error_concealment=3; -static int lavc_param_gray=0; -static int lavc_param_vstats=0; -static int lavc_param_idct_algo=0; -static int lavc_param_debug=0; -static int lavc_param_vismv=0; -static int lavc_param_skip_top=0; -static int lavc_param_skip_bottom=0; -static int lavc_param_fast=0; -static int lavc_param_lowres=0; -static char *lavc_param_lowres_str=NULL; -static char *lavc_param_skip_loop_filter_str = NULL; -static char *lavc_param_skip_idct_str = NULL; -static char *lavc_param_skip_frame_str = NULL; -static int lavc_param_threads=1; -static int lavc_param_bitexact=0; -static char *lavc_avopt = NULL; - const m_option_t lavc_decode_opts_conf[]={ - {"bug", &lavc_param_workaround_bugs, CONF_TYPE_INT, CONF_RANGE, -1, 999999, NULL}, - {"er", &lavc_param_error_resilience, CONF_TYPE_INT, CONF_RANGE, 0, 99, NULL}, - {"gray", &lavc_param_gray, CONF_TYPE_FLAG, 0, 0, CODEC_FLAG_PART, NULL}, - {"idct", &lavc_param_idct_algo, CONF_TYPE_INT, CONF_RANGE, 0, 99, NULL}, - {"ec", &lavc_param_error_concealment, CONF_TYPE_INT, CONF_RANGE, 0, 99, NULL}, - {"vstats", &lavc_param_vstats, CONF_TYPE_FLAG, 0, 0, 1, NULL}, - {"debug", &lavc_param_debug, CONF_TYPE_INT, CONF_RANGE, 0, 9999999, NULL}, - {"vismv", &lavc_param_vismv, CONF_TYPE_INT, CONF_RANGE, 0, 9999999, NULL}, - {"st", &lavc_param_skip_top, CONF_TYPE_INT, CONF_RANGE, 0, 999, NULL}, - {"sb", &lavc_param_skip_bottom, CONF_TYPE_INT, CONF_RANGE, 0, 999, NULL}, - {"fast", &lavc_param_fast, CONF_TYPE_FLAG, 0, 0, CODEC_FLAG2_FAST, NULL}, - {"lowres", &lavc_param_lowres_str, CONF_TYPE_STRING, 0, 0, 0, NULL}, - {"skiploopfilter", &lavc_param_skip_loop_filter_str, CONF_TYPE_STRING, 0, 0, 0, NULL}, - {"skipidct", &lavc_param_skip_idct_str, CONF_TYPE_STRING, 0, 0, 0, NULL}, - {"skipframe", &lavc_param_skip_frame_str, CONF_TYPE_STRING, 0, 0, 0, NULL}, - {"threads", &lavc_param_threads, CONF_TYPE_INT, CONF_RANGE, 1, 8, NULL}, - {"bitexact", &lavc_param_bitexact, CONF_TYPE_FLAG, 0, 0, CODEC_FLAG_BITEXACT, NULL}, - {"o", &lavc_avopt, CONF_TYPE_STRING, 0, 0, 0, NULL}, + OPT_INTRANGE("bug", lavc_param.workaround_bugs, 0, -1, 999999), + OPT_INTRANGE("er", lavc_param.error_resilience, 0, 0, 99), + OPT_FLAG_ON("gray", lavc_param.gray, 0), + OPT_INTRANGE("idct", lavc_param.idct_algo, 0, 0, 99), + OPT_INTRANGE("ec", lavc_param.error_concealment, 0, 0, 99), + OPT_FLAG_ON("vstats", lavc_param.vstats, 0), + OPT_INTRANGE("debug", lavc_param.debug, 0, 0, 9999999), + OPT_INTRANGE("vismv", lavc_param.vismv, 0, 0, 9999999), + OPT_INTRANGE("st", lavc_param.skip_top, 0, 0, 999), + OPT_INTRANGE("sb", lavc_param.skip_bottom, 0, 0, 999), + OPT_FLAG_CONSTANTS("fast", lavc_param.fast, 0, 0, CODEC_FLAG2_FAST), + OPT_STRING("lowres", lavc_param.lowres_str, 0), + OPT_STRING("skiploopfilter", lavc_param.skip_loop_filter_str, 0), + OPT_STRING("skipidct", lavc_param.skip_idct_str, 0), + OPT_STRING("skipframe", lavc_param.skip_frame_str, 0), + OPT_INTRANGE("threads", lavc_param.threads, 0, 1, 8), + OPT_FLAG_CONSTANTS("bitexact", lavc_param.bitexact, 0, 0, CODEC_FLAG_BITEXACT), + OPT_STRING("o", lavc_param.avopt, 0), {NULL, NULL, 0, 0, 0, 0, NULL} }; @@ -150,7 +132,7 @@ static int control(sh_video_t *sh, int cmd, void *arg, ...){ return CONTROL_UNKNOWN; } -void mp_msp_av_log_callback(void *ptr, int level, const char *fmt, va_list vl) +static void mp_msp_av_log_callback(void *ptr, int level, const char *fmt, va_list vl) { static int print_prefix=1; AVClass *avc= ptr ? *(AVClass **)ptr : NULL; @@ -202,11 +184,12 @@ void mp_msp_av_log_callback(void *ptr, int level, const char *fmt, va_list vl) // init driver static int init(sh_video_t *sh){ + struct lavc_param *lavc_param = &sh->opts->lavc_param; AVCodecContext *avctx; vd_ffmpeg_ctx *ctx; AVCodec *lavc_codec; int lowres_w=0; - int do_vis_debug= lavc_param_vismv || (lavc_param_debug&(FF_DEBUG_VIS_MB_TYPE|FF_DEBUG_VIS_QP)); + int do_vis_debug= lavc_param->vismv || (lavc_param->debug&(FF_DEBUG_VIS_MB_TYPE|FF_DEBUG_VIS_QP)); if(!avcodec_initialized){ avcodec_init(); @@ -227,7 +210,7 @@ static int init(sh_video_t *sh){ return 0; } - if(vd_use_slices && (lavc_codec->capabilities&CODEC_CAP_DRAW_HORIZ_BAND) && !do_vis_debug) + if(sh->opts->vd_use_slices && (lavc_codec->capabilities&CODEC_CAP_DRAW_HORIZ_BAND) && !do_vis_debug) ctx->do_slices=1; if(lavc_codec->capabilities&CODEC_CAP_DR1 && !do_vis_debug && lavc_codec->id != CODEC_ID_H264 && lavc_codec->id != CODEC_ID_INTERPLAY_VIDEO && lavc_codec->id != CODEC_ID_ROQ) @@ -257,38 +240,38 @@ static int init(sh_video_t *sh){ avctx->reget_buffer= get_buffer; } - avctx->flags|= lavc_param_bitexact; + avctx->flags|= lavc_param->bitexact; avctx->width = sh->disp_w; avctx->height= sh->disp_h; - avctx->workaround_bugs= lavc_param_workaround_bugs; - avctx->error_recognition= lavc_param_error_resilience; - if(lavc_param_gray) avctx->flags|= CODEC_FLAG_GRAY; - avctx->flags2|= lavc_param_fast; + avctx->workaround_bugs= lavc_param->workaround_bugs; + avctx->error_recognition= lavc_param->error_resilience; + if(lavc_param->gray) avctx->flags|= CODEC_FLAG_GRAY; + avctx->flags2|= lavc_param->fast; avctx->codec_tag= sh->format; avctx->stream_codec_tag= sh->video.fccHandler; - avctx->idct_algo= lavc_param_idct_algo; - avctx->error_concealment= lavc_param_error_concealment; - avctx->debug= lavc_param_debug; - if (lavc_param_debug) + avctx->idct_algo= lavc_param->idct_algo; + avctx->error_concealment= lavc_param->error_concealment; + avctx->debug= lavc_param->debug; + if (lavc_param->debug) av_log_set_level(AV_LOG_DEBUG); - avctx->debug_mv= lavc_param_vismv; - avctx->skip_top = lavc_param_skip_top; - avctx->skip_bottom= lavc_param_skip_bottom; - if(lavc_param_lowres_str != NULL) + avctx->debug_mv= lavc_param->vismv; + avctx->skip_top = lavc_param->skip_top; + avctx->skip_bottom= lavc_param->skip_bottom; + if(lavc_param->lowres_str != NULL) { - sscanf(lavc_param_lowres_str, "%d,%d", &lavc_param_lowres, &lowres_w); - if(lavc_param_lowres < 1 || lavc_param_lowres > 16 || (lowres_w > 0 && avctx->width < lowres_w)) - lavc_param_lowres = 0; - avctx->lowres = lavc_param_lowres; - } - avctx->skip_loop_filter = str2AVDiscard(lavc_param_skip_loop_filter_str); - avctx->skip_idct = str2AVDiscard(lavc_param_skip_idct_str); - avctx->skip_frame = str2AVDiscard(lavc_param_skip_frame_str); - - if(lavc_avopt){ - if(parse_avopts(avctx, lavc_avopt) < 0){ - mp_msg(MSGT_DECVIDEO, MSGL_ERR, "Your options /%s/ look like gibberish to me pal\n", lavc_avopt); + sscanf(lavc_param->lowres_str, "%d,%d", &ctx->lowres, &lowres_w); + if(ctx->lowres < 1 || ctx->lowres > 16 || (lowres_w > 0 && avctx->width < lowres_w)) + ctx->lowres = 0; + avctx->lowres = ctx->lowres; + } + avctx->skip_loop_filter = str2AVDiscard(lavc_param->skip_loop_filter_str); + avctx->skip_idct = str2AVDiscard(lavc_param->skip_idct_str); + avctx->skip_frame = str2AVDiscard(lavc_param->skip_frame_str); + + if(lavc_param->avopt){ + if(parse_avopts(avctx, lavc_param->avopt) < 0){ + mp_msg(MSGT_DECVIDEO, MSGL_ERR, "Your options /%s/ look like gibberish to me pal\n", lavc_param->avopt); uninit(sh); return 0; } @@ -380,8 +363,8 @@ static int init(sh_video_t *sh){ if(sh->bih) avctx->bits_per_coded_sample= sh->bih->biBitCount; - if(lavc_param_threads > 1) - avcodec_thread_init(avctx, lavc_param_threads); + if(lavc_param->threads > 1) + avcodec_thread_init(avctx, lavc_param->threads); /* open it */ if (avcodec_open(avctx, lavc_codec) < 0) { mp_msg(MSGT_DECVIDEO, MSGL_ERR, MSGTR_CantOpenCodec); @@ -397,7 +380,7 @@ static void uninit(sh_video_t *sh){ vd_ffmpeg_ctx *ctx = sh->context; AVCodecContext *avctx = ctx->avctx; - if(lavc_param_vstats){ + if(sh->opts->lavc_param.vstats){ int i; for(i=1; i<32; i++){ mp_msg(MSGT_DECVIDEO, MSGL_INFO, "QP: %d, count: %d\n", i, ctx->qp_stat[i]); @@ -424,14 +407,15 @@ static void uninit(sh_video_t *sh){ } static void draw_slice(struct AVCodecContext *s, - AVFrame *src, int offset[4], - int y, int type, int height){ + const AVFrame *src, int offset[4], + int y, int type, int height){ sh_video_t *sh = s->opaque; uint8_t *source[3]= {src->data[0] + offset[0], src->data[1] + offset[1], src->data[2] + offset[2]}; #if 0 int start=0, i; int width= s->width; - int skip_stride= ((width<<lavc_param_lowres)+15)>>4; + vd_ffmpeg_ctx *ctx = sh->context; + int skip_stride= ((width << ctx->lowres)+15)>>4; uint8_t *skip= &s->coded_frame->mbskip_table[(y>>4)*skip_stride]; int threshold= s->coded_frame->age; if(s->pict_type!=B_TYPE){ @@ -469,8 +453,8 @@ static int init_vo(sh_video_t *sh, enum PixelFormat pix_fmt){ // if sh->ImageDesc is non-NULL, it means we decode QuickTime(tm) video. // use dimensions from BIH to avoid black borders at the right and bottom. if (sh->bih && sh->ImageDesc) { - width = sh->bih->biWidth>>lavc_param_lowres; - height = sh->bih->biHeight>>lavc_param_lowres; + width = sh->bih->biWidth >> ctx->lowres; + height = sh->bih->biHeight >> ctx->lowres; } // it is possible another vo buffers to be used after vo config() @@ -711,7 +695,7 @@ typedef struct dp_hdr_s { uint32_t chunktab; // offset to chunk offset array } dp_hdr_t; -void swap_palette(void *pal) { +static void swap_palette(void *pal) { int i; uint32_t *p = pal; for (i = 0; i < AVPALETTE_COUNT; i++) @@ -725,6 +709,7 @@ static mp_image_t *decode(sh_video_t *sh, void *data, int len, int flags){ vd_ffmpeg_ctx *ctx = sh->context; AVFrame *pic= ctx->pic; AVCodecContext *avctx = ctx->avctx; + struct lavc_param *lavc_param = &sh->opts->lavc_param; mp_image_t *mpi=NULL; int dr1= ctx->do_dr1; @@ -755,7 +740,7 @@ static mp_image_t *decode(sh_video_t *sh, void *data, int len, int flags){ if(ret<0) mp_msg(MSGT_DECVIDEO, MSGL_WARN, "Error while decoding frame!\n"); //printf("repeat: %d\n", pic->repeat_pict); //-- vstats generation - while(lavc_param_vstats){ // always one time loop + while(lavc_param->vstats){ // always one time loop static FILE *fvstats=NULL; char filename[20]; static long long int all_len=0; @@ -774,7 +759,7 @@ static mp_image_t *decode(sh_video_t *sh, void *data, int len, int flags){ fvstats = fopen(filename, "w"); if(!fvstats) { perror("fopen"); - lavc_param_vstats=0; // disable block + lavc_param->vstats=0; // disable block break; /*exit(1);*/ } @@ -783,8 +768,8 @@ static mp_image_t *decode(sh_video_t *sh, void *data, int len, int flags){ // average MB quantizer { int x, y; - int w = ((avctx->width << lavc_param_lowres)+15) >> 4; - int h = ((avctx->height << lavc_param_lowres)+15) >> 4; + int w = ((avctx->width << ctx->lowres)+15) >> 4; + int h = ((avctx->height << ctx->lowres)+15) >> 4; int8_t *q = pic->qscale_table; for(y = 0; y < h; y++) { for(x = 0; x < w; x++) diff --git a/libmpcodecs/vd_hmblck.c b/libmpcodecs/vd_hmblck.c index 18f26f45e1..096f081d18 100644 --- a/libmpcodecs/vd_hmblck.c +++ b/libmpcodecs/vd_hmblck.c @@ -8,7 +8,7 @@ #define TEMP_BUF_SIZE (720*576) -static vd_info_t info = { +static const vd_info_t info = { "Hauppauge Macroblock/NV12/NV21 Decoder", "hmblck", "Alex <d18c7db@hotmail.com>, A'rpi, Alex Beregszaszi", diff --git a/libmpcodecs/vd_ijpg.c b/libmpcodecs/vd_ijpg.c index a54b339c8f..3338067872 100644 --- a/libmpcodecs/vd_ijpg.c +++ b/libmpcodecs/vd_ijpg.c @@ -16,7 +16,7 @@ #include "vd_internal.h" -static vd_info_t info = { +static const vd_info_t info = { "JPEG Images decoder", "ijpg", "Pontscho", @@ -93,7 +93,7 @@ METHODDEF(void) skip_input_data (j_decompress_ptr cinfo, long num_bytes) METHODDEF(void) term_source (j_decompress_ptr cinfo) { } -GLOBAL(void) jpeg_buf_src ( j_decompress_ptr cinfo, char * inbuf,int bufsize ) +static void jpeg_buf_src ( j_decompress_ptr cinfo, char * inbuf,int bufsize ) { my_src_ptr src; if (cinfo->src == NULL) cinfo->src=malloc( sizeof( my_source_mgr ) ); diff --git a/libmpcodecs/vd_internal.h b/libmpcodecs/vd_internal.h index d04903e26a..dee8448cb1 100644 --- a/libmpcodecs/vd_internal.h +++ b/libmpcodecs/vd_internal.h @@ -19,7 +19,7 @@ static int init(sh_video_t *sh); static void uninit(sh_video_t *sh); static mp_image_t* decode(sh_video_t *sh,void* data,int len,int flags); -#define LIBVD_EXTERN(x) vd_functions_t mpcodecs_vd_##x = {\ +#define LIBVD_EXTERN(x) const vd_functions_t mpcodecs_vd_##x = {\ &info,\ init,\ uninit,\ diff --git a/libmpcodecs/vd_libdv.c b/libmpcodecs/vd_libdv.c index f7c1e4db03..8f5c6996ed 100644 --- a/libmpcodecs/vd_libdv.c +++ b/libmpcodecs/vd_libdv.c @@ -18,7 +18,7 @@ #include "vd_internal.h" -static vd_info_t info = +static const vd_info_t info = { "Raw DV Video Decoder", "libdv", diff --git a/libmpcodecs/vd_libmpeg2.c b/libmpcodecs/vd_libmpeg2.c index fdcb5cd2e3..ef7671e3ce 100644 --- a/libmpcodecs/vd_libmpeg2.c +++ b/libmpcodecs/vd_libmpeg2.c @@ -2,14 +2,14 @@ #include <stdlib.h> #include "config.h" - +#include "options.h" #include "mp_msg.h" #include "vd_internal.h" //#undef MPEG12_POSTPROC -static vd_info_t info = +static const vd_info_t info = { "libmpeg2 MPEG 1/2 Video decoder", "libmpeg2", @@ -221,7 +221,7 @@ static mp_image_t* decode(sh_video_t *sh,void* data,int len,int flags){ } mpeg2_skip(mpeg2dec, 0); //mpeg2skip skips frames until set again to 0 - use_callback = (!framedrop && vd_use_slices && + use_callback = (!framedrop && sh->opts->vd_use_slices && (info->current_picture->flags&PIC_FLAG_PROGRESSIVE_FRAME)) ? MP_IMGFLAG_DRAW_CALLBACK:0; diff --git a/libmpcodecs/vd_lzo.c b/libmpcodecs/vd_lzo.c index 5371e4115f..a60436cbe5 100644 --- a/libmpcodecs/vd_lzo.c +++ b/libmpcodecs/vd_lzo.c @@ -9,7 +9,7 @@ #define MOD_NAME "DecLZO" -static vd_info_t info = { +static const vd_info_t info = { "LZO compressed Video", "lzo", "Tilmann Bitterberg", diff --git a/libmpcodecs/vd_mpegpes.c b/libmpcodecs/vd_mpegpes.c index 033df36fa6..598b1203ba 100644 --- a/libmpcodecs/vd_mpegpes.c +++ b/libmpcodecs/vd_mpegpes.c @@ -7,7 +7,7 @@ #include "vd_internal.h" -static vd_info_t info = +static const vd_info_t info = { "MPEG 1/2 Video passthrough", "mpegpes", diff --git a/libmpcodecs/vd_mpng.c b/libmpcodecs/vd_mpng.c index f4af973e8d..cab4cf66d4 100644 --- a/libmpcodecs/vd_mpng.c +++ b/libmpcodecs/vd_mpng.c @@ -12,7 +12,7 @@ #include "vd_internal.h" -static vd_info_t info = { +static const vd_info_t info = { "PNG Images decoder", "mpng", "A'rpi", diff --git a/libmpcodecs/vd_mtga.c b/libmpcodecs/vd_mtga.c index c9e0c24555..61022c71c8 100644 --- a/libmpcodecs/vd_mtga.c +++ b/libmpcodecs/vd_mtga.c @@ -16,7 +16,7 @@ #include "vd_internal.h" -static vd_info_t info = +static const vd_info_t info = { "TGA Images decoder", "mtga", diff --git a/libmpcodecs/vd_null.c b/libmpcodecs/vd_null.c index a82a3ba036..34392962b1 100644 --- a/libmpcodecs/vd_null.c +++ b/libmpcodecs/vd_null.c @@ -6,7 +6,7 @@ #include "vd_internal.h" -static vd_info_t info = +static const vd_info_t info = { "Null video decoder", "null", diff --git a/libmpcodecs/vd_nuv.c b/libmpcodecs/vd_nuv.c index cb89ddb391..21ed42ec1d 100644 --- a/libmpcodecs/vd_nuv.c +++ b/libmpcodecs/vd_nuv.c @@ -6,7 +6,7 @@ #include "vd_internal.h" -static vd_info_t info = { +static const vd_info_t info = { "NuppelVideo decoder", "nuv", "A'rpi", diff --git a/libmpcodecs/vd_qtvideo.c b/libmpcodecs/vd_qtvideo.c index a1bada8a6e..8b32cf9a6d 100644 --- a/libmpcodecs/vd_qtvideo.c +++ b/libmpcodecs/vd_qtvideo.c @@ -16,7 +16,7 @@ #include "loader/wine/windef.h" #endif -static vd_info_t info = { +static const vd_info_t info = { "Quicktime Video decoder", "qtvideo", "A'rpi", diff --git a/libmpcodecs/vd_raw.c b/libmpcodecs/vd_raw.c index d025fd0060..7eeda88c00 100644 --- a/libmpcodecs/vd_raw.c +++ b/libmpcodecs/vd_raw.c @@ -6,7 +6,7 @@ #include "vd_internal.h" -static vd_info_t info = { +static const vd_info_t info = { "RAW Uncompressed Video", "raw", "A'rpi", diff --git a/libmpcodecs/vd_realvid.c b/libmpcodecs/vd_realvid.c index 93b303fe8f..fcb464fec8 100644 --- a/libmpcodecs/vd_realvid.c +++ b/libmpcodecs/vd_realvid.c @@ -14,7 +14,7 @@ #include "vd_internal.h" #include "loader/wine/windef.h" -static vd_info_t info = { +static const vd_info_t info = { "RealVideo decoder", "realvid", "Alex Beregszaszi", diff --git a/libmpcodecs/vd_sgi.c b/libmpcodecs/vd_sgi.c index 1496b041e3..e4e72285b9 100644 --- a/libmpcodecs/vd_sgi.c +++ b/libmpcodecs/vd_sgi.c @@ -21,7 +21,7 @@ #define OUT_PIXEL_STRIDE 3 /* RGB */ -static vd_info_t info = +static const vd_info_t info = { "SGI Image decoder", "sgi", diff --git a/libmpcodecs/vd_theora.c b/libmpcodecs/vd_theora.c index 3ed2f88354..69beb08198 100644 --- a/libmpcodecs/vd_theora.c +++ b/libmpcodecs/vd_theora.c @@ -9,7 +9,7 @@ #include "vd_internal.h" -static vd_info_t info = { +static const vd_info_t info = { "Theora/VP3", "theora", "David Kuehling", diff --git a/libmpcodecs/vd_vfw.c b/libmpcodecs/vd_vfw.c index de11b49f40..afe17f7c6a 100644 --- a/libmpcodecs/vd_vfw.c +++ b/libmpcodecs/vd_vfw.c @@ -10,7 +10,7 @@ #include "loader/wine/driver.h" #include "loader/wine/vfw.h" -static vd_info_t info = { +static const vd_info_t info = { #ifdef BUILD_VFWEX "Win32/VfWex video codecs", "vfwex", diff --git a/libmpcodecs/vd_xanim.c b/libmpcodecs/vd_xanim.c index 05f8945bbb..eb06eef122 100644 --- a/libmpcodecs/vd_xanim.c +++ b/libmpcodecs/vd_xanim.c @@ -18,7 +18,7 @@ #include "vd_internal.h" -static vd_info_t info = { +static const vd_info_t info = { "XAnim codecs", "xanim", "A'rpi & Alex", diff --git a/libmpcodecs/vd_xvid4.c b/libmpcodecs/vd_xvid4.c index c144043946..54d3a2a563 100644 --- a/libmpcodecs/vd_xvid4.c +++ b/libmpcodecs/vd_xvid4.c @@ -378,7 +378,7 @@ static float stats2aspect(xvid_dec_stats_t *stats) * Module structure definition ****************************************************************************/ -static vd_info_t info = +static const vd_info_t info = { "XviD 1.0 decoder", "xvid", diff --git a/libmpcodecs/vd_zrmjpeg.c b/libmpcodecs/vd_zrmjpeg.c index fb73d06511..2d35ec1420 100644 --- a/libmpcodecs/vd_zrmjpeg.c +++ b/libmpcodecs/vd_zrmjpeg.c @@ -36,7 +36,7 @@ #include "vd_internal.h" -static vd_info_t info = +static const vd_info_t info = { "Zoran MJPEG Video passthrough", "zrmjpeg", diff --git a/libmpcodecs/ve.c b/libmpcodecs/ve.c index dd7f650ba8..9d083f5d86 100644 --- a/libmpcodecs/ve.c +++ b/libmpcodecs/ve.c @@ -51,8 +51,8 @@ static vf_info_t* encoder_list[]={ NULL }; -vf_instance_t* vf_open_encoder(vf_instance_t* next, const char *name, char *args){ +vf_instance_t* vf_open_encoder(struct MPOpts *opts, vf_instance_t* next, const char *name, char *args){ char* vf_args[] = { "_oldargs_", args, NULL }; - return vf_open_plugin(encoder_list,next,name,vf_args); + return vf_open_plugin(opts, encoder_list,next,name,vf_args); } diff --git a/libmpcodecs/ve_lavc.c b/libmpcodecs/ve_lavc.c index bbb5d69ed1..606de43a87 100644 --- a/libmpcodecs/ve_lavc.c +++ b/libmpcodecs/ve_lavc.c @@ -325,9 +325,9 @@ struct vf_priv_s { #define mux_v (vf->priv->mux) #define lavc_venc_context (vf->priv->context) -static int encode_frame(struct vf_instance_s* vf, AVFrame *pic, double pts); +static int encode_frame(struct vf_instance* vf, AVFrame *pic, double pts); -static int config(struct vf_instance_s* vf, +static int config(struct vf_instance* vf, int width, int height, int d_width, int d_height, unsigned int flags, unsigned int outfmt){ int size, i; @@ -717,7 +717,7 @@ static int config(struct vf_instance_s* vf, return 1; } -static int control(struct vf_instance_s* vf, int request, void* data){ +static int control(struct vf_instance* vf, int request, void* data){ switch(request){ case VFCTRL_FLUSH_FRAMES: @@ -729,7 +729,7 @@ static int control(struct vf_instance_s* vf, int request, void* data){ } } -static int query_format(struct vf_instance_s* vf, unsigned int fmt){ +static int query_format(struct vf_instance* vf, unsigned int fmt){ switch(fmt){ case IMGFMT_YV12: case IMGFMT_IYUV: @@ -766,7 +766,7 @@ static double psnr(double d){ return -10.0*log(d)/log(10); } -static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){ +static int put_image(struct vf_instance* vf, mp_image_t *mpi, double pts){ AVFrame *pic= vf->priv->pic; pic->data[0]=mpi->planes[0]; @@ -789,7 +789,7 @@ static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){ return encode_frame(vf, pic, pts) >= 0; } -static int encode_frame(struct vf_instance_s* vf, AVFrame *pic, double pts){ +static int encode_frame(struct vf_instance* vf, AVFrame *pic, double pts){ const char pict_type_char[5]= {'?', 'I', 'P', 'B', 'S'}; int out_size; double dts; @@ -894,7 +894,7 @@ static int encode_frame(struct vf_instance_s* vf, AVFrame *pic, double pts){ return out_size; } -static void uninit(struct vf_instance_s* vf){ +static void uninit(struct vf_instance* vf){ if(lavc_param_psnr){ double f= lavc_venc_context->width*lavc_venc_context->height*255.0*255.0; diff --git a/libmpcodecs/ve_libdv.c b/libmpcodecs/ve_libdv.c index fab9628d3c..da0f261d58 100644 --- a/libmpcodecs/ve_libdv.c +++ b/libmpcodecs/ve_libdv.c @@ -37,7 +37,7 @@ struct vf_priv_s { //===========================================================================// -static int config(struct vf_instance_s* vf, +static int config(struct vf_instance* vf, int width, int height, int d_width, int d_height, unsigned int flags, unsigned int outfmt){ @@ -59,18 +59,18 @@ static int config(struct vf_instance_s* vf, return 1; } -static int control(struct vf_instance_s* vf, int request, void* data){ +static int control(struct vf_instance* vf, int request, void* data){ return CONTROL_UNKNOWN; } -static int query_format(struct vf_instance_s* vf, unsigned int fmt){ +static int query_format(struct vf_instance* vf, unsigned int fmt){ if(fmt==IMGFMT_YUY2) return VFCAP_CSP_SUPPORTED | VFCAP_CSP_SUPPORTED_BY_HW; if(fmt==IMGFMT_RGB24) return VFCAP_CSP_SUPPORTED; return 0; } -static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){ +static int put_image(struct vf_instance* vf, mp_image_t *mpi, double pts){ dv_encode_full_frame(vf->priv->enc, mpi->planes, (mpi->flags&MP_IMGFLAG_YUV) ? e_dv_color_yuv : e_dv_color_rgb, diff --git a/libmpcodecs/ve_nuv.c b/libmpcodecs/ve_nuv.c index 0b670179cd..91473627da 100644 --- a/libmpcodecs/ve_nuv.c +++ b/libmpcodecs/ve_nuv.c @@ -68,7 +68,7 @@ m_option_t nuvopts_conf[]={ //===========================================================================// -static int config(struct vf_instance_s* vf, +static int config(struct vf_instance* vf, int width, int height, int d_width, int d_height, unsigned int flags, unsigned int outfmt){ @@ -88,17 +88,17 @@ static int config(struct vf_instance_s* vf, return 1; } -static int control(struct vf_instance_s* vf, int request, void* data){ +static int control(struct vf_instance* vf, int request, void* data){ return CONTROL_UNKNOWN; } -static int query_format(struct vf_instance_s* vf, unsigned int fmt){ +static int query_format(struct vf_instance* vf, unsigned int fmt){ if(fmt==IMGFMT_I420) return VFCAP_CSP_SUPPORTED | VFCAP_CSP_SUPPORTED_BY_HW; return 0; } -static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){ +static int put_image(struct vf_instance* vf, mp_image_t *mpi, double pts){ struct rtframeheader* ench = (struct rtframeheader*)vf->priv->buffer; uint8_t* data = vf->priv->buffer + FRAMEHEADERSIZE; uint8_t* zdata = vf->priv->zbuffer + FRAMEHEADERSIZE; @@ -180,7 +180,7 @@ static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){ return 1; } -static void uninit(struct vf_instance_s* vf) { +static void uninit(struct vf_instance* vf) { if(vf->priv->buffer) free(vf->priv->buffer); diff --git a/libmpcodecs/ve_qtvideo.c b/libmpcodecs/ve_qtvideo.c index 238f539df8..9e890a348b 100644 --- a/libmpcodecs/ve_qtvideo.c +++ b/libmpcodecs/ve_qtvideo.c @@ -139,7 +139,7 @@ struct vf_priv_s { //===========================================================================// -static int config(struct vf_instance_s* vf, +static int config(struct vf_instance* vf, int width, int height, int d_width, int d_height, unsigned int flags, unsigned int outfmt){ // OSErr cres; @@ -177,19 +177,19 @@ static int config(struct vf_instance_s* vf, return 1; } -static int control(struct vf_instance_s* vf, int request, void* data){ +static int control(struct vf_instance* vf, int request, void* data){ return CONTROL_UNKNOWN; } -static int query_format(struct vf_instance_s* vf, unsigned int fmt){ +static int query_format(struct vf_instance* vf, unsigned int fmt){ if(fmt==IMGFMT_YUY2) return VFCAP_CSP_SUPPORTED | VFCAP_CSP_SUPPORTED_BY_HW; return 0; } static int codec_initialized = 0; -static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){ +static int put_image(struct vf_instance* vf, mp_image_t *mpi, double pts){ OSErr cres; long framesizemax; diff --git a/libmpcodecs/ve_raw.c b/libmpcodecs/ve_raw.c index 9cbc75c256..225fd3bfaf 100644 --- a/libmpcodecs/ve_raw.c +++ b/libmpcodecs/ve_raw.c @@ -26,7 +26,7 @@ struct vf_priv_s { }; #define mux_v (vf->priv->mux) -static int set_format(struct vf_instance_s *vf, unsigned int fmt) { +static int set_format(struct vf_instance *vf, unsigned int fmt) { if (!force_fourcc) mux_v->bih->biCompression = fmt; @@ -82,7 +82,7 @@ static int set_format(struct vf_instance_s *vf, unsigned int fmt) { } -static int config(struct vf_instance_s *vf, +static int config(struct vf_instance *vf, int width, int height, int d_width, int d_height, unsigned int flags, unsigned int outfmt) { @@ -97,11 +97,11 @@ static int config(struct vf_instance_s *vf, return 1; } -static int control(struct vf_instance_s *vf, int request, void *data) { +static int control(struct vf_instance *vf, int request, void *data) { return CONTROL_UNKNOWN; } -static int query_format(struct vf_instance_s *vf, unsigned int fmt) { +static int query_format(struct vf_instance *vf, unsigned int fmt) { if (IMGFMT_IS_RGB(fmt) || IMGFMT_IS_BGR(fmt)) return VFCAP_CSP_SUPPORTED | VFCAP_CSP_SUPPORTED_BY_HW; switch (fmt) { @@ -122,7 +122,7 @@ static int query_format(struct vf_instance_s *vf, unsigned int fmt) { return 0; } -static int put_image(struct vf_instance_s *vf, mp_image_t *mpi, double pts) { +static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts) { mux_v->buffer = mpi->planes[0]; muxer_write_chunk(mux_v, mpi->width*mpi->height*mux_v->bih->biBitCount/8, 0x10, pts, pts); return 1; diff --git a/libmpcodecs/ve_vfw.c b/libmpcodecs/ve_vfw.c index d9425601bd..ddceb428a2 100644 --- a/libmpcodecs/ve_vfw.c +++ b/libmpcodecs/ve_vfw.c @@ -259,7 +259,7 @@ static int vfw_encode_frame(BITMAPINFOHEADER* biOutput,void* OutBuf, #define mux_v (vf->priv->mux) #define vfw_bih (vf->priv->bih) -static int config(struct vf_instance_s* vf, +static int config(struct vf_instance* vf, int width, int height, int d_width, int d_height, unsigned int flags, unsigned int outfmt){ @@ -277,17 +277,17 @@ static int config(struct vf_instance_s* vf, return 1; } -static int control(struct vf_instance_s* vf, int request, void* data){ +static int control(struct vf_instance* vf, int request, void* data){ return CONTROL_UNKNOWN; } -static int query_format(struct vf_instance_s* vf, unsigned int fmt){ +static int query_format(struct vf_instance* vf, unsigned int fmt){ if(fmt==IMGFMT_BGR24) return VFCAP_CSP_SUPPORTED | VFCAP_CSP_SUPPORTED_BY_HW | VFCAP_FLIPPED; return 0; } -static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){ +static int put_image(struct vf_instance* vf, mp_image_t *mpi, double pts){ long flags=0; int ret; // flip_upside_down(vo_image_ptr,vo_image_ptr,3*vo_w,vo_h); // dirty hack @@ -298,7 +298,7 @@ static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){ return 1; } -static void uninit(struct vf_instance_s* vf) +static void uninit(struct vf_instance* vf) { HRESULT ret; diff --git a/libmpcodecs/ve_x264.c b/libmpcodecs/ve_x264.c index 04d0bd342a..724619ad04 100644 --- a/libmpcodecs/ve_x264.c +++ b/libmpcodecs/ve_x264.c @@ -73,8 +73,8 @@ static int encode_nals(uint8_t *buf, int size, x264_nal_t *nals, int nnal){ return p - buf; } -static int put_image(struct vf_instance_s *vf, mp_image_t *mpi, double pts); -static int encode_frame(struct vf_instance_s *vf, x264_picture_t *pic_in); +static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts); +static int encode_frame(struct vf_instance *vf, x264_picture_t *pic_in); void x264enc_set_param(const m_option_t* opt, char* arg) { @@ -148,7 +148,7 @@ void x264enc_set_param(const m_option_t* opt, char* arg) } } -static int config(struct vf_instance_s* vf, int width, int height, int d_width, int d_height, unsigned int flags, unsigned int outfmt) { +static int config(struct vf_instance* vf, int width, int height, int d_width, int d_height, unsigned int flags, unsigned int outfmt) { h264_module_t *mod=(h264_module_t*)vf->priv; if(parse_error) @@ -215,7 +215,7 @@ static int config(struct vf_instance_s* vf, int width, int height, int d_width, return 1; } -static int control(struct vf_instance_s* vf, int request, void *data) +static int control(struct vf_instance* vf, int request, void *data) { h264_module_t *mod=(h264_module_t*)vf->priv; switch(request){ @@ -228,7 +228,7 @@ static int control(struct vf_instance_s* vf, int request, void *data) } } -static int query_format(struct vf_instance_s* vf, unsigned int fmt) +static int query_format(struct vf_instance* vf, unsigned int fmt) { switch(fmt) { case IMGFMT_I420: @@ -247,7 +247,7 @@ static int query_format(struct vf_instance_s* vf, unsigned int fmt) return 0; } -static int put_image(struct vf_instance_s *vf, mp_image_t *mpi, double pts) +static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts) { h264_module_t *mod=(h264_module_t*)vf->priv; int i; @@ -265,7 +265,7 @@ static int put_image(struct vf_instance_s *vf, mp_image_t *mpi, double pts) return encode_frame(vf, &mod->pic) >= 0; } -static int encode_frame(struct vf_instance_s *vf, x264_picture_t *pic_in) +static int encode_frame(struct vf_instance *vf, x264_picture_t *pic_in) { h264_module_t *mod=(h264_module_t*)vf->priv; x264_picture_t pic_out; @@ -296,7 +296,7 @@ static int encode_frame(struct vf_instance_s *vf, x264_picture_t *pic_in) return i_size; } -static void uninit(struct vf_instance_s *vf) +static void uninit(struct vf_instance *vf) { h264_module_t *mod=(h264_module_t*)vf->priv; if (mod->x264) diff --git a/libmpcodecs/ve_xvid4.c b/libmpcodecs/ve_xvid4.c index 8a2c2c542b..2b55f7744f 100644 --- a/libmpcodecs/ve_xvid4.c +++ b/libmpcodecs/ve_xvid4.c @@ -374,7 +374,7 @@ static const char *errorstring(int err); *==========================================================================*/ static int -config(struct vf_instance_s* vf, +config(struct vf_instance* vf, int width, int height, int d_width, int d_height, unsigned int flags, unsigned int outfmt) { @@ -439,7 +439,7 @@ config(struct vf_instance_s* vf, *==========================================================================*/ static void -uninit(struct vf_instance_s* vf) +uninit(struct vf_instance* vf) { xvid_mplayer_module_t *mod = (xvid_mplayer_module_t *)vf->priv; @@ -477,7 +477,7 @@ uninit(struct vf_instance_s* vf) *==========================================================================*/ static int -control(struct vf_instance_s* vf, int request, void* data) +control(struct vf_instance* vf, int request, void* data) { xvid_mplayer_module_t *mod = (xvid_mplayer_module_t *)vf->priv; @@ -495,7 +495,7 @@ xvid_mplayer_module_t *mod = (xvid_mplayer_module_t *)vf->priv; *==========================================================================*/ static int -query_format(struct vf_instance_s* vf, unsigned int fmt) +query_format(struct vf_instance* vf, unsigned int fmt) { switch(fmt){ case IMGFMT_YV12: @@ -514,7 +514,7 @@ query_format(struct vf_instance_s* vf, unsigned int fmt) *==========================================================================*/ static int -put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts) +put_image(struct vf_instance* vf, mp_image_t *mpi, double pts) { int size; xvid_enc_stats_t stats; diff --git a/libmpcodecs/vf.c b/libmpcodecs/vf.c index 2371b0fdff..c2b88b5584 100644 --- a/libmpcodecs/vf.c +++ b/libmpcodecs/vf.c @@ -195,7 +195,6 @@ static const vf_info_t* const filter_list[]={ }; // For the vf option -m_obj_settings_t* vf_settings = NULL; const m_obj_list_t vf_obj_list = { (void**)filter_list, M_ST_OFF(vf_info_t,name), @@ -436,12 +435,12 @@ mp_image_t* vf_get_image(vf_instance_t* vf, unsigned int outfmt, int mp_imgtype, //============================================================================ // By default vf doesn't accept MPEGPES -static int vf_default_query_format(struct vf_instance_s* vf, unsigned int fmt){ +static int vf_default_query_format(struct vf_instance* vf, unsigned int fmt){ if(fmt == IMGFMT_MPEGPES) return 0; return vf_next_query_format(vf,fmt); } -vf_instance_t* vf_open_plugin(const vf_info_t* const* filter_list, vf_instance_t* next, const char *name, char **args){ +vf_instance_t* vf_open_plugin(struct MPOpts *opts, const vf_info_t* const* filter_list, vf_instance_t* next, const char *name, char **args){ vf_instance_t* vf; int i; for(i=0;;i++){ @@ -451,8 +450,8 @@ vf_instance_t* vf_open_plugin(const vf_info_t* const* filter_list, vf_instance_t } if(!strcmp(filter_list[i]->name,name)) break; } - vf=malloc(sizeof(vf_instance_t)); - memset(vf,0,sizeof(vf_instance_t)); + vf = calloc(1, sizeof *vf); + vf->opts = opts; vf->info=filter_list[i]; vf->next=next; vf->config=vf_next_config; @@ -480,7 +479,7 @@ vf_instance_t* vf_open_plugin(const vf_info_t* const* filter_list, vf_instance_t return NULL; } -vf_instance_t* vf_open_filter(vf_instance_t* next, const char *name, char **args){ +vf_instance_t* vf_open_filter(struct MPOpts *opts, vf_instance_t* next, const char *name, char **args){ if(args && strcmp(args[0],"_oldargs_")) { int i,l = 0; for(i = 0 ; args && args[2*i] ; i++) @@ -502,7 +501,7 @@ vf_instance_t* vf_open_filter(vf_instance_t* next, const char *name, char **args mp_msg(MSGT_VFILTER,MSGL_INFO,MSGTR_OpeningVideoFilter "[%s]\n", name); } - return vf_open_plugin(filter_list,next,name,args); + return vf_open_plugin(opts, filter_list,next,name,args); } /** @@ -513,11 +512,12 @@ vf_instance_t* vf_open_filter(vf_instance_t* next, const char *name, char **args * \return pointer to the filter instance that was created. */ vf_instance_t* vf_add_before_vo(vf_instance_t **vf, char *name, char **args) { + struct MPOpts *opts = (*vf)->opts; vf_instance_t *vo, *prev = NULL, *new; // Find the last filter (should be vf_vo) for (vo = *vf; vo->next; vo = vo->next) prev = vo; - new = vf_open_filter(vo, name, args); + new = vf_open_filter(opts, vo, name, args); if (prev) prev->next = new; else @@ -529,6 +529,7 @@ vf_instance_t* vf_add_before_vo(vf_instance_t **vf, char *name, char **args) { unsigned int vf_match_csp(vf_instance_t** vfp,const unsigned int* list,unsigned int preferred){ vf_instance_t* vf=*vfp; + struct MPOpts *opts = vf->opts; const unsigned int* p; unsigned int best=0; int ret; @@ -542,7 +543,7 @@ unsigned int vf_match_csp(vf_instance_t** vfp,const unsigned int* list,unsigned if(best) return best; // bingo, they have common csp! // ok, then try with scale: if(vf->info == &vf_info_scale) return 0; // avoid infinite recursion! - vf=vf_open_filter(vf,"scale",NULL); + vf=vf_open_filter(opts, vf,"scale",NULL); if(!vf) return 0; // failed to init "scale" // try the preferred csp first: if(preferred && vf->query_format(vf,preferred)) best=preferred; else @@ -593,12 +594,6 @@ int vf_output_queued_frame(vf_instance_t *vf) tmp = last->continue_buffered_image; last->continue_buffered_image = NULL; ret = tmp(last); - if (ret > 0) { - vf->control(vf, VFCTRL_DRAW_OSD, NULL); -#ifdef CONFIG_ASS - vf->control(vf, VFCTRL_DRAW_EOSD, NULL); -#endif - } if (ret) return ret; } @@ -617,7 +612,7 @@ int vf_output_queued_frame(vf_instance_t *vf) * are unchanged, and returns either success or error. * */ -int vf_config_wrapper(struct vf_instance_s* vf, +int vf_config_wrapper(struct vf_instance* vf, int width, int height, int d_width, int d_height, unsigned int flags, unsigned int outfmt) { @@ -640,9 +635,10 @@ int vf_config_wrapper(struct vf_instance_s* vf, return r; } -int vf_next_config(struct vf_instance_s* vf, +int vf_next_config(struct vf_instance* vf, int width, int height, int d_width, int d_height, unsigned int voflags, unsigned int outfmt){ + struct MPOpts *opts = vf->opts; int miss; int flags=vf->next->query_format(vf->next,outfmt); if(!flags){ @@ -650,7 +646,7 @@ int vf_next_config(struct vf_instance_s* vf, // let's insert the 'scale' filter, it does the job for us: vf_instance_t* vf2; if(vf->next->info==&vf_info_scale) return 0; // scale->scale - vf2=vf_open_filter(vf->next,"scale",NULL); + vf2=vf_open_filter(opts, vf->next,"scale",NULL); if(!vf2) return 0; // shouldn't happen! vf->next=vf2; flags=vf->next->query_format(vf->next,outfmt); @@ -664,7 +660,7 @@ int vf_next_config(struct vf_instance_s* vf, if(miss&VFCAP_ACCEPT_STRIDE){ // vf requires stride support but vf->next doesn't support it! // let's insert the 'expand' filter, it does the job for us: - vf_instance_t* vf2=vf_open_filter(vf->next,"expand",NULL); + vf_instance_t* vf2=vf_open_filter(opts, vf->next,"expand",NULL); if(!vf2) return 0; // shouldn't happen! vf->next=vf2; } @@ -672,29 +668,21 @@ int vf_next_config(struct vf_instance_s* vf, return vf_config_wrapper(vf->next,width,height,d_width,d_height,voflags,outfmt); } -int vf_next_control(struct vf_instance_s* vf, int request, void* data){ +int vf_next_control(struct vf_instance* vf, int request, void* data){ return vf->next->control(vf->next,request,data); } -void vf_extra_flip(struct vf_instance_s* vf) { - vf_next_control(vf, VFCTRL_DRAW_OSD, NULL); -#ifdef CONFIG_ASS - vf_next_control(vf, VFCTRL_DRAW_EOSD, NULL); -#endif - vf_next_control(vf, VFCTRL_FLIP_PAGE, NULL); -} - -int vf_next_query_format(struct vf_instance_s* vf, unsigned int fmt){ +int vf_next_query_format(struct vf_instance* vf, unsigned int fmt){ int flags=vf->next->query_format(vf->next,fmt); if(flags) flags|=vf->default_caps; return flags; } -int vf_next_put_image(struct vf_instance_s* vf,mp_image_t *mpi, double pts){ +int vf_next_put_image(struct vf_instance* vf,mp_image_t *mpi, double pts){ return vf->next->put_image(vf->next,mpi, pts); } -void vf_next_draw_slice(struct vf_instance_s* vf,unsigned char** src, int * stride,int w, int h, int x, int y){ +void vf_next_draw_slice(struct vf_instance* vf,unsigned char** src, int * stride,int w, int h, int x, int y){ if (vf->next->draw_slice) { vf->next->draw_slice(vf->next,src,stride,w,h,x,y); return; @@ -718,7 +706,10 @@ void vf_next_draw_slice(struct vf_instance_s* vf,unsigned char** src, int * stri //============================================================================ -vf_instance_t* append_filters(vf_instance_t* last){ +vf_instance_t *append_filters(vf_instance_t* last, + struct m_obj_settings *vf_settings) +{ + struct MPOpts *opts = last->opts; vf_instance_t* vf; int i; @@ -728,7 +719,7 @@ vf_instance_t* append_filters(vf_instance_t* last){ /* NOP */; for(i-- ; i >= 0 ; i--) { //printf("Open filter %s\n",vf_settings[i].name); - vf = vf_open_filter(last,vf_settings[i].name,vf_settings[i].attribs); + vf = vf_open_filter(opts, last,vf_settings[i].name,vf_settings[i].attribs); if(vf) last=vf; } } diff --git a/libmpcodecs/vf.h b/libmpcodecs/vf.h index e96d3fb26d..95e4ff51e7 100644 --- a/libmpcodecs/vf.h +++ b/libmpcodecs/vf.h @@ -3,7 +3,8 @@ #include "mp_image.h" -struct vf_instance_s; +struct MPOpts; +struct vf_instance; struct vf_priv_s; typedef struct vf_info_s { @@ -11,7 +12,7 @@ typedef struct vf_info_s { const char *name; const char *author; const char *comment; - int (*open)(struct vf_instance_s* vf,char* args); + int (*open)(struct vf_instance* vf,char* args); // Ptr to a struct dscribing the options const void* opts; } vf_info_t; @@ -31,27 +32,27 @@ typedef struct vf_format_context_t { int orig_width, orig_height, orig_fmt; } vf_format_context_t; -typedef struct vf_instance_s { +typedef struct vf_instance { const vf_info_t* info; // funcs: - int (*config)(struct vf_instance_s* vf, + int (*config)(struct vf_instance* vf, int width, int height, int d_width, int d_height, unsigned int flags, unsigned int outfmt); - int (*control)(struct vf_instance_s* vf, + int (*control)(struct vf_instance* vf, int request, void* data); - int (*query_format)(struct vf_instance_s* vf, + int (*query_format)(struct vf_instance* vf, unsigned int fmt); - void (*get_image)(struct vf_instance_s* vf, + void (*get_image)(struct vf_instance* vf, mp_image_t *mpi); - int (*put_image)(struct vf_instance_s* vf, + int (*put_image)(struct vf_instance* vf, mp_image_t *mpi, double pts); - void (*start_slice)(struct vf_instance_s* vf, + void (*start_slice)(struct vf_instance* vf, mp_image_t *mpi); - void (*draw_slice)(struct vf_instance_s* vf, + void (*draw_slice)(struct vf_instance* vf, unsigned char** src, int* stride, int w,int h, int x, int y); - void (*uninit)(struct vf_instance_s* vf); + void (*uninit)(struct vf_instance* vf); - int (*continue_buffered_image)(struct vf_instance_s* vf); + int (*continue_buffered_image)(struct vf_instance* vf); // caps: unsigned int default_caps; // used by default query_format() unsigned int default_reqs; // used by default config() @@ -59,9 +60,10 @@ typedef struct vf_instance_s { int w, h; vf_image_context_t imgctx; vf_format_context_t fmt; - struct vf_instance_s* next; + struct vf_instance* next; mp_image_t *dmpi; struct vf_priv_s* priv; + struct MPOpts *opts; } vf_instance_t; // control codes: @@ -89,6 +91,10 @@ typedef struct vf_seteq_s #define VFCTRL_GET_PTS 17 /* Return last pts value that reached vf_vo*/ #define VFCTRL_SET_DEINTERLACE 18 /* Set deinterlacing status */ #define VFCTRL_GET_DEINTERLACE 19 /* Get deinterlacing status */ +/* Hack to make the OSD state object available to vf_expand which accesses + * the OSD state outside of normal OSD draw time. */ +#define VFCTRL_SET_OSD_OBJ 20 +#define VFCTRL_REDRAW_OSD 21 /* Change user-visible OSD immediately */ #include "vfcap.h" @@ -100,10 +106,10 @@ typedef struct vf_seteq_s void vf_mpi_clear(mp_image_t* mpi,int x0,int y0,int w,int h); mp_image_t* vf_get_image(vf_instance_t* vf, unsigned int outfmt, int mp_imgtype, int mp_imgflag, int w, int h); -vf_instance_t* vf_open_plugin(const vf_info_t* const* filter_list, vf_instance_t* next, const char *name, char **args); -vf_instance_t* vf_open_filter(vf_instance_t* next, const char *name, char **args); +vf_instance_t* vf_open_plugin(struct MPOpts *opts, const vf_info_t* const* filter_list, vf_instance_t* next, const char *name, char **args); +vf_instance_t* vf_open_filter(struct MPOpts *opts, vf_instance_t* next, const char *name, char **args); vf_instance_t* vf_add_before_vo(vf_instance_t **vf, char *name, char **args); -vf_instance_t* vf_open_encoder(vf_instance_t* next, const char *name, char *args); +vf_instance_t* vf_open_encoder(struct MPOpts *opts, vf_instance_t* next, const char *name, char *args); unsigned int vf_match_csp(vf_instance_t** vfp,const unsigned int* list,unsigned int preferred); void vf_clone_mpi_attributes(mp_image_t* dst, mp_image_t* src); @@ -111,21 +117,21 @@ void vf_queue_frame(vf_instance_t *vf, int (*)(vf_instance_t *)); int vf_output_queued_frame(vf_instance_t *vf); // default wrappers: -int vf_next_config(struct vf_instance_s* vf, +int vf_next_config(struct vf_instance* vf, int width, int height, int d_width, int d_height, unsigned int flags, unsigned int outfmt); -int vf_next_control(struct vf_instance_s* vf, int request, void* data); -void vf_extra_flip(struct vf_instance_s* vf); -int vf_next_query_format(struct vf_instance_s* vf, unsigned int fmt); -int vf_next_put_image(struct vf_instance_s* vf,mp_image_t *mpi, double pts); -void vf_next_draw_slice (struct vf_instance_s* vf, unsigned char** src, int* stride, int w,int h, int x, int y); +int vf_next_control(struct vf_instance* vf, int request, void* data); +int vf_next_query_format(struct vf_instance* vf, unsigned int fmt); +int vf_next_put_image(struct vf_instance* vf,mp_image_t *mpi, double pts); +void vf_next_draw_slice (struct vf_instance* vf, unsigned char** src, int* stride, int w,int h, int x, int y); -vf_instance_t* append_filters(vf_instance_t* last); +struct m_obj_settings; +vf_instance_t* append_filters(vf_instance_t* last, struct m_obj_settings *vf_settings); void vf_uninit_filter(vf_instance_t* vf); void vf_uninit_filter_chain(vf_instance_t* vf); -int vf_config_wrapper(struct vf_instance_s* vf, +int vf_config_wrapper(struct vf_instance* vf, int width, int height, int d_width, int d_height, unsigned int flags, unsigned int outfmt); diff --git a/libmpcodecs/vf_1bpp.c b/libmpcodecs/vf_1bpp.c index 873e431855..c4fd04c338 100644 --- a/libmpcodecs/vf_1bpp.c +++ b/libmpcodecs/vf_1bpp.c @@ -40,7 +40,7 @@ static const unsigned int bgr_list[]={ 0 }; -static unsigned int find_best(struct vf_instance_s* vf){ +static unsigned int find_best(struct vf_instance* vf){ unsigned int best=0; int ret; const unsigned int* p=bgr_list; @@ -60,7 +60,7 @@ struct vf_priv_s { unsigned int fmt; }; -static int config(struct vf_instance_s* vf, +static int config(struct vf_instance* vf, int width, int height, int d_width, int d_height, unsigned int flags, unsigned int outfmt){ if (!vf->priv->fmt) @@ -103,7 +103,7 @@ static void convert(mp_image_t *mpi, mp_image_t *dmpi, int value0, int value1,in } } -static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){ +static int put_image(struct vf_instance* vf, mp_image_t *mpi, double pts){ mp_image_t *dmpi; // hope we'll get DR buffer: @@ -154,7 +154,7 @@ static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){ //===========================================================================// -static int query_format(struct vf_instance_s* vf, unsigned int fmt){ +static int query_format(struct vf_instance* vf, unsigned int fmt){ int best; if(fmt!=IMGFMT_RGB1 && fmt!=IMGFMT_BGR1) return 0; best=find_best(vf); diff --git a/libmpcodecs/vf_2xsai.c b/libmpcodecs/vf_2xsai.c index 97a0182767..7405606697 100644 --- a/libmpcodecs/vf_2xsai.c +++ b/libmpcodecs/vf_2xsai.c @@ -25,7 +25,7 @@ static int PixelsPerMask = 2; #define makecol(r,g,b) (r+(g<<8)+(b<<16)) #define makecol_depth(d,r,g,b) (r+(g<<8)+(b<<16)) -int Init_2xSaI(int d) +static int Init_2xSaI(int d) { int minr = 0, ming = 0, minb = 0; @@ -77,7 +77,7 @@ int Init_2xSaI(int d) + ((((A & qlowpixelMask) + (B & qlowpixelMask) + (C & qlowpixelMask) + (D & qlowpixelMask)) >> 2) & qlowpixelMask) -void Super2xSaI_ex(uint8_t *src, uint32_t src_pitch, +static void Super2xSaI_ex(uint8_t *src, uint32_t src_pitch, uint8_t *dst, uint32_t dst_pitch, uint32_t width, uint32_t height, int sbpp) { @@ -262,7 +262,7 @@ void Super2xSaI_ex(uint8_t *src, uint32_t src_pitch, //===========================================================================// -static int config(struct vf_instance_s* vf, +static int config(struct vf_instance* vf, int width, int height, int d_width, int d_height, unsigned int flags, unsigned int outfmt){ @@ -271,7 +271,7 @@ static int config(struct vf_instance_s* vf, return vf_next_config(vf,2*width,2*height,2*d_width,2*d_height,flags,outfmt); } -static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){ +static int put_image(struct vf_instance* vf, mp_image_t *mpi, double pts){ mp_image_t *dmpi; // hope we'll get DR buffer: @@ -288,7 +288,7 @@ static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){ //===========================================================================// -static int query_format(struct vf_instance_s* vf, unsigned int fmt){ +static int query_format(struct vf_instance* vf, unsigned int fmt){ switch(fmt){ // case IMGFMT_BGR15: // case IMGFMT_BGR16: diff --git a/libmpcodecs/vf_ass.c b/libmpcodecs/vf_ass.c index f33aba44b7..30bdcb0149 100644 --- a/libmpcodecs/vf_ass.c +++ b/libmpcodecs/vf_ass.c @@ -31,6 +31,7 @@ #include "config.h" #include "mp_msg.h" #include "help_mp.h" +#include "options.h" #include "img_format.h" #include "mp_image.h" @@ -65,33 +66,34 @@ static const struct vf_priv_s { ass_renderer_t* ass_priv; unsigned char* planes[3]; - unsigned char* dirty_rows; + struct line_limits { + uint16_t start; + uint16_t end; + } *line_limits; } vf_priv_dflt; -extern int opt_screen_size_x; -extern int opt_screen_size_y; - extern ass_track_t* ass_track; extern float sub_delay; extern int sub_visibility; -static int config(struct vf_instance_s* vf, +static int config(struct vf_instance* vf, int width, int height, int d_width, int d_height, unsigned int flags, unsigned int outfmt) { + struct MPOpts *opts = vf->opts; if (outfmt == IMGFMT_IF09) return 0; vf->priv->outh = height + ass_top_margin + ass_bottom_margin; vf->priv->outw = width; - if(!opt_screen_size_x && !opt_screen_size_y){ + if (!opts->screen_size_x && !opts->screen_size_y) { d_width = d_width * vf->priv->outw / width; d_height = d_height * vf->priv->outh / height; } vf->priv->planes[1] = malloc(vf->priv->outw * vf->priv->outh); vf->priv->planes[2] = malloc(vf->priv->outw * vf->priv->outh); - vf->priv->dirty_rows = malloc(vf->priv->outh); + vf->priv->line_limits = malloc((vf->priv->outh + 1) / 2 * sizeof(*vf->priv->line_limits)); if (vf->priv->ass_priv) { ass_configure(vf->priv->ass_priv, vf->priv->outw, vf->priv->outh, 0); @@ -101,7 +103,7 @@ static int config(struct vf_instance_s* vf, return vf_next_config(vf, vf->priv->outw, vf->priv->outh, d_width, d_height, flags, outfmt); } -static void get_image(struct vf_instance_s* vf, mp_image_t *mpi) +static void get_image(struct vf_instance* vf, mp_image_t *mpi) { if(mpi->type == MP_IMGTYPE_IPB) return; if(mpi->flags & MP_IMGFLAG_PRESERVE) return; @@ -160,7 +162,7 @@ static void blank(mp_image_t *mpi, int y1, int y2) } } -static int prepare_image(struct vf_instance_s* vf, mp_image_t *mpi) +static int prepare_image(struct vf_instance* vf, mp_image_t *mpi) { if(mpi->flags&MP_IMGFLAG_DIRECT || mpi->flags&MP_IMGFLAG_DRAW_CALLBACK){ vf->dmpi = mpi->priv; @@ -205,55 +207,58 @@ static int prepare_image(struct vf_instance_s* vf, mp_image_t *mpi) return 0; } +static void update_limits(struct vf_instance *vf, int starty, int endy, + int startx, int endx) +{ + starty >>= 1; + endy = (endy + 1) >> 1; + startx >>= 1; + endx = (endx + 1) >> 1; + for (int i = starty; i < endy; i++) { + struct line_limits *ll = vf->priv->line_limits + i; + if (startx < ll->start) + ll->start = startx; + if (endx > ll->end) + ll->end = endx; + } +} + /** * \brief Copy specified rows from render_context.dmpi to render_context.planes, upsampling to 4:4:4 */ -static void copy_from_image(struct vf_instance_s* vf, int first_row, int last_row) +static void copy_from_image(struct vf_instance* vf) { int pl; - int i, j, k; - unsigned char val; - int chroma_rows; - - first_row -= (first_row % 2); - last_row += (last_row % 2); - chroma_rows = (last_row - first_row) / 2; for (pl = 1; pl < 3; ++pl) { int dst_stride = vf->priv->outw; int src_stride = vf->dmpi->stride[pl]; - unsigned char* src = vf->dmpi->planes[pl] + (first_row/2) * src_stride; - unsigned char* dst = vf->priv->planes[pl] + first_row * dst_stride; - unsigned char* dst_next = dst + dst_stride; - for(i = 0; i < chroma_rows; ++i) - { - if ((vf->priv->dirty_rows[first_row + i*2] == 0) || - (vf->priv->dirty_rows[first_row + i*2 + 1] == 0)) { - for (j = 0, k = 0; j < vf->dmpi->chroma_width; ++j, k+=2) { - val = *(src + j); - *(dst + k) = val; - *(dst + k + 1) = val; - *(dst_next + k) = val; - *(dst_next + k + 1) = val; - } + unsigned char* src = vf->dmpi->planes[pl]; + unsigned char* dst = vf->priv->planes[pl]; + for (int i = 0; i < (vf->priv->outh + 1) / 2; i++) { + struct line_limits *ll = vf->priv->line_limits + i; + unsigned char* dst_next = dst + dst_stride; + for (int j = ll->start; j < ll->end; j++) { + unsigned char val = src[j]; + dst[j << 1] = val; + dst[(j << 1) + 1] = val; + dst_next[j << 1] = val; + dst_next[(j << 1) + 1] = val; } src += src_stride; dst = dst_next + dst_stride; - dst_next = dst + dst_stride; } } - for (i = first_row; i < last_row; ++i) - vf->priv->dirty_rows[i] = 1; } /** * \brief Copy all previously copied rows back to render_context.dmpi */ -static void copy_to_image(struct vf_instance_s* vf) +static void copy_to_image(struct vf_instance* vf) { int pl; - int i, j, k; + int i, j; for (pl = 1; pl < 3; ++pl) { int dst_stride = vf->dmpi->stride[pl]; int src_stride = vf->priv->outw; @@ -261,18 +266,14 @@ static void copy_to_image(struct vf_instance_s* vf) unsigned char* dst = vf->dmpi->planes[pl]; unsigned char* src = vf->priv->planes[pl]; unsigned char* src_next = vf->priv->planes[pl] + src_stride; - for(i = 0; i < vf->dmpi->chroma_height; ++i) - { - if ((vf->priv->dirty_rows[i*2] == 1)) { - assert(vf->priv->dirty_rows[i*2 + 1] == 1); - for (j = 0, k = 0; j < vf->dmpi->chroma_width; ++j, k+=2) { - unsigned val = 0; - val += *(src + k); - val += *(src + k + 1); - val += *(src_next + k); - val += *(src_next + k + 1); - *(dst + j) = val >> 2; - } + for (i = 0; i < vf->dmpi->chroma_height; ++i) { + for (j = vf->priv->line_limits[i].start; j < vf->priv->line_limits[i].end; j++) { + unsigned val = 0; + val += src[j << 1]; + val += src[(j << 1) + 1]; + val += src_next[j << 1]; + val += src_next[(j << 1) + 1]; + dst[j] = val >> 2; } dst += dst_stride; src = src_next + src_stride; @@ -281,7 +282,7 @@ static void copy_to_image(struct vf_instance_s* vf) } } -static void my_draw_bitmap(struct vf_instance_s* vf, unsigned char* bitmap, int bitmap_w, int bitmap_h, int stride, int dst_x, int dst_y, unsigned color) +static void my_draw_bitmap(struct vf_instance* vf, unsigned char* bitmap, int bitmap_w, int bitmap_h, int stride, int dst_x, int dst_y, unsigned color) { unsigned char y = rgba2y(color); unsigned char u = rgba2u(color); @@ -297,10 +298,10 @@ static void my_draw_bitmap(struct vf_instance_s* vf, unsigned char* bitmap, int dstv = vf->priv->planes[2] + dst_x + dst_y * vf->priv->outw; for (i = 0; i < bitmap_h; ++i) { for (j = 0; j < bitmap_w; ++j) { - unsigned k = ((unsigned)src[j]) * opacity / 255; - dsty[j] = (k*y + (255-k)*dsty[j]) / 255; - dstu[j] = (k*u + (255-k)*dstu[j]) / 255; - dstv[j] = (k*v + (255-k)*dstv[j]) / 255; + unsigned k = (src[j] * opacity + 255) >> 8; + dsty[j] = (k*y + (255-k)*dsty[j] + 255) >> 8; + dstu[j] = (k*u + (255-k)*dstu[j] + 255) >> 8; + dstv[j] = (k*v + (255-k)*dstv[j] + 255) >> 8; } src += stride; dsty += dmpi->stride[0]; @@ -309,12 +310,15 @@ static void my_draw_bitmap(struct vf_instance_s* vf, unsigned char* bitmap, int } } -static int render_frame(struct vf_instance_s* vf, mp_image_t *mpi, const ass_image_t* img) +static int render_frame(struct vf_instance* vf, mp_image_t *mpi, const ass_image_t* img) { if (img) { - memset(vf->priv->dirty_rows, 0, vf->priv->outh); // reset dirty rows + for (int i = 0; i < (vf->priv->outh + 1) / 2; i++) + vf->priv->line_limits[i] = (struct line_limits){65535, 0}; + for (const ass_image_t *im = img; im; im = im->next) + update_limits(vf, im->dst_y, im->dst_y + im->h, im->dst_x, im->dst_x + im->w); + copy_from_image(vf); while (img) { - copy_from_image(vf, img->dst_y, img->dst_y + img->h); my_draw_bitmap(vf, img->bitmap, img->w, img->h, img->stride, img->dst_x, img->dst_y, img->color); img = img->next; @@ -324,7 +328,7 @@ static int render_frame(struct vf_instance_s* vf, mp_image_t *mpi, const ass_ima return 0; } -static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts) +static int put_image(struct vf_instance* vf, mp_image_t *mpi, double pts) { ass_image_t* images = 0; if (sub_visibility && vf->priv->ass_priv && ass_track && (pts != MP_NOPTS_VALUE)) @@ -336,7 +340,7 @@ static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts) return vf_next_put_image(vf, vf->dmpi, pts); } -static int query_format(struct vf_instance_s* vf, unsigned int fmt) +static int query_format(struct vf_instance* vf, unsigned int fmt) { switch(fmt){ case IMGFMT_YV12: @@ -362,16 +366,13 @@ static int control(vf_instance_t *vf, int request, void *data) return vf_next_control(vf, request, data); } -static void uninit(struct vf_instance_s* vf) +static void uninit(struct vf_instance* vf) { if (vf->priv->ass_priv) ass_renderer_done(vf->priv->ass_priv); - if (vf->priv->planes[1]) - free(vf->priv->planes[1]); - if (vf->priv->planes[2]) - free(vf->priv->planes[2]); - if (vf->priv->dirty_rows) - free(vf->priv->dirty_rows); + free(vf->priv->planes[1]); + free(vf->priv->planes[2]); + free(vf->priv->line_limits); } static const unsigned int fmt_list[]={ diff --git a/libmpcodecs/vf_blackframe.c b/libmpcodecs/vf_blackframe.c index dce13ea927..34d2f1f506 100644 --- a/libmpcodecs/vf_blackframe.c +++ b/libmpcodecs/vf_blackframe.c @@ -40,12 +40,12 @@ struct vf_priv_s { unsigned int bamount, bthresh, frame, lastkeyframe; }; -static int config(struct vf_instance_s* vf, int width, int height, int d_width, +static int config(struct vf_instance* vf, int width, int height, int d_width, int d_height, unsigned int flags, unsigned int outfmt) { return vf_next_config(vf,width,height,d_width,d_height,flags,outfmt); } -static int query_format(struct vf_instance_s *vf, unsigned fmt) { +static int query_format(struct vf_instance *vf, unsigned fmt) { switch(fmt) { case IMGFMT_YVU9: case IMGFMT_IF09: @@ -66,7 +66,7 @@ static int query_format(struct vf_instance_s *vf, unsigned fmt) { return 0; } -static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){ +static int put_image(struct vf_instance* vf, mp_image_t *mpi, double pts){ mp_image_t *dmpi; int x, y; int nblack=0, pblack=0; @@ -110,11 +110,11 @@ static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){ return vf_next_put_image(vf, dmpi, pts); } -static int control(struct vf_instance_s* vf, int request, void* data){ +static int control(struct vf_instance* vf, int request, void* data){ return vf_next_control(vf,request,data); } -static void uninit(struct vf_instance_s *vf) { +static void uninit(struct vf_instance *vf) { if (vf->priv) free(vf->priv); } diff --git a/libmpcodecs/vf_bmovl.c b/libmpcodecs/vf_bmovl.c index 80b61ca502..1c16d60ca7 100644 --- a/libmpcodecs/vf_bmovl.c +++ b/libmpcodecs/vf_bmovl.c @@ -125,14 +125,14 @@ struct vf_priv_s { }; static int -query_format(struct vf_instance_s* vf, unsigned int fmt){ +query_format(struct vf_instance* vf, unsigned int fmt){ if(fmt==IMGFMT_YV12) return VFCAP_CSP_SUPPORTED; return 0; } static int -config(struct vf_instance_s* vf, +config(struct vf_instance* vf, int width, int height, int d_width, int d_height, unsigned int flags, unsigned int outfmt) { @@ -162,7 +162,7 @@ config(struct vf_instance_s* vf, } static void -uninit(struct vf_instance_s *vf) +uninit(struct vf_instance *vf) { if(vf->priv) { free(vf->priv->bitmap.y); @@ -214,7 +214,7 @@ _read_cmd(int fd, char *cmd, char *args) { static int -put_image(struct vf_instance_s* vf, mp_image_t* mpi, double pts){ +put_image(struct vf_instance* vf, mp_image_t* mpi, double pts){ int buf_x=0, buf_y=0, buf_pos=0; int have, got, want; int xpos=0, ypos=0, pos=0; diff --git a/libmpcodecs/vf_boxblur.c b/libmpcodecs/vf_boxblur.c index b27b1a6d01..bad900f45c 100644 --- a/libmpcodecs/vf_boxblur.c +++ b/libmpcodecs/vf_boxblur.c @@ -52,7 +52,7 @@ struct vf_priv_s { /***************************************************************************/ -static int config(struct vf_instance_s* vf, +static int config(struct vf_instance* vf, int width, int height, int d_width, int d_height, unsigned int flags, unsigned int outfmt){ @@ -133,7 +133,7 @@ static void vBlur(uint8_t *dst, uint8_t *src, int w, int h, int dstStride, int s } } -static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){ +static int put_image(struct vf_instance* vf, mp_image_t *mpi, double pts){ int cw= mpi->w >> mpi->chroma_x_shift; int ch= mpi->h >> mpi->chroma_y_shift; @@ -162,7 +162,7 @@ static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){ //===========================================================================// -static int query_format(struct vf_instance_s* vf, unsigned int fmt){ +static int query_format(struct vf_instance* vf, unsigned int fmt){ switch(fmt) { case IMGFMT_YV12: diff --git a/libmpcodecs/vf_crop.c b/libmpcodecs/vf_crop.c index c9bd11c6c7..ca14927956 100644 --- a/libmpcodecs/vf_crop.c +++ b/libmpcodecs/vf_crop.c @@ -5,6 +5,7 @@ #include "config.h" #include "mp_msg.h" #include "help_mp.h" +#include "options.h" #include "img_format.h" #include "mp_image.h" @@ -21,14 +22,12 @@ static const struct vf_priv_s { -1,-1 }; -extern int opt_screen_size_x; -extern int opt_screen_size_y; - //===========================================================================// -static int config(struct vf_instance_s* vf, +static int config(struct vf_instance* vf, int width, int height, int d_width, int d_height, unsigned int flags, unsigned int outfmt){ + struct MPOpts *opts = vf->opts; // calculate the missing parameters: if(vf->priv->crop_w<=0 || vf->priv->crop_w>width) vf->priv->crop_w=width; if(vf->priv->crop_h<=0 || vf->priv->crop_h>height) vf->priv->crop_h=height; @@ -61,14 +60,14 @@ static int config(struct vf_instance_s* vf, mp_msg(MSGT_VFILTER, MSGL_WARN, MSGTR_MPCODECS_CropBadPositionWidthHeight); return 0; } - if(!opt_screen_size_x && !opt_screen_size_y){ + if(!opts->screen_size_x && !opts->screen_size_y){ d_width=d_width*vf->priv->crop_w/width; d_height=d_height*vf->priv->crop_h/height; } return vf_next_config(vf,vf->priv->crop_w,vf->priv->crop_h,d_width,d_height,flags,outfmt); } -static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){ +static int put_image(struct vf_instance* vf, mp_image_t *mpi, double pts){ mp_image_t *dmpi; if (mpi->flags&MP_IMGFLAG_DRAW_CALLBACK) return vf_next_put_image(vf,vf->dmpi, pts); @@ -95,12 +94,12 @@ static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){ return vf_next_put_image(vf,dmpi, pts); } -static void start_slice(struct vf_instance_s* vf, mp_image_t *mpi){ +static void start_slice(struct vf_instance* vf, mp_image_t *mpi){ vf->dmpi = vf_get_image(vf->next, mpi->imgfmt, mpi->type, mpi->flags, vf->priv->crop_w, vf->priv->crop_h); } -static void draw_slice(struct vf_instance_s* vf, +static void draw_slice(struct vf_instance* vf, unsigned char** src, int* stride, int w,int h, int x, int y){ unsigned char *src2[3]; src2[0] = src[0]; diff --git a/libmpcodecs/vf_cropdetect.c b/libmpcodecs/vf_cropdetect.c index 31389d5fb0..68e6eb1011 100644 --- a/libmpcodecs/vf_cropdetect.c +++ b/libmpcodecs/vf_cropdetect.c @@ -42,7 +42,7 @@ static int checkline(unsigned char* src,int stride,int len,int bpp){ //===========================================================================// -static int config(struct vf_instance_s* vf, +static int config(struct vf_instance* vf, int width, int height, int d_width, int d_height, unsigned int flags, unsigned int outfmt){ vf->priv->x1=width - 1; @@ -53,7 +53,7 @@ static int config(struct vf_instance_s* vf, return vf_next_config(vf,width,height,d_width,d_height,flags,outfmt); } -static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){ +static int put_image(struct vf_instance* vf, mp_image_t *mpi, double pts){ mp_image_t *dmpi; int bpp=mpi->bpp/8; int w,h,x,y,shrink_by; @@ -136,7 +136,7 @@ if(++vf->priv->fno>2){ // ignore first 2 frames - they may be empty return vf_next_put_image(vf,dmpi, pts); } -static int query_format(struct vf_instance_s* vf, unsigned int fmt) { +static int query_format(struct vf_instance* vf, unsigned int fmt) { switch(fmt) { // the default limit value works only right with YV12 right now. case IMGFMT_YV12: diff --git a/libmpcodecs/vf_decimate.c b/libmpcodecs/vf_decimate.c index e1cea34ae3..36afff3b7d 100644 --- a/libmpcodecs/vf_decimate.c +++ b/libmpcodecs/vf_decimate.c @@ -110,7 +110,7 @@ static int diff_to_drop(int hi, int lo, float frac, mp_image_t *old, mp_image_t new->w*(new->bpp/8), new->h, old->stride[0], new->stride[0]); } -static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts) +static int put_image(struct vf_instance* vf, mp_image_t *mpi, double pts) { mp_image_t *dmpi; @@ -146,7 +146,7 @@ static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts) return vf_next_put_image(vf, dmpi, pts); } -static void uninit(struct vf_instance_s* vf) +static void uninit(struct vf_instance* vf) { free(vf->priv); } diff --git a/libmpcodecs/vf_delogo.c b/libmpcodecs/vf_delogo.c index 2afa0afc33..666a5b8690 100644 --- a/libmpcodecs/vf_delogo.c +++ b/libmpcodecs/vf_delogo.c @@ -123,7 +123,7 @@ static void delogo(uint8_t *dst, uint8_t *src, int dstStride, int srcStride, int } } -static int config(struct vf_instance_s* vf, +static int config(struct vf_instance* vf, int width, int height, int d_width, int d_height, unsigned int flags, unsigned int outfmt){ @@ -131,7 +131,7 @@ static int config(struct vf_instance_s* vf, } -static void get_image(struct vf_instance_s* vf, mp_image_t *mpi){ +static void get_image(struct vf_instance* vf, mp_image_t *mpi){ if(mpi->flags&MP_IMGFLAG_PRESERVE) return; // don't change if(mpi->imgfmt!=vf->priv->outfmt) return; // colorspace differ // ok, we can do pp in-place (or pp disabled): @@ -149,7 +149,7 @@ static void get_image(struct vf_instance_s* vf, mp_image_t *mpi){ mpi->flags|=MP_IMGFLAG_DIRECT; } -static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){ +static int put_image(struct vf_instance* vf, mp_image_t *mpi, double pts){ mp_image_t *dmpi; if(!(mpi->flags&MP_IMGFLAG_DIRECT)){ @@ -175,7 +175,7 @@ static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){ return vf_next_put_image(vf,dmpi, pts); } -static void uninit(struct vf_instance_s* vf){ +static void uninit(struct vf_instance* vf){ if(!vf->priv) return; free(vf->priv); @@ -184,7 +184,7 @@ static void uninit(struct vf_instance_s* vf){ //===========================================================================// -static int query_format(struct vf_instance_s* vf, unsigned int fmt){ +static int query_format(struct vf_instance* vf, unsigned int fmt){ switch(fmt) { case IMGFMT_YV12: @@ -195,7 +195,7 @@ static int query_format(struct vf_instance_s* vf, unsigned int fmt){ return 0; } -static unsigned int fmt_list[]={ +static const unsigned int fmt_list[]={ IMGFMT_YV12, IMGFMT_I420, IMGFMT_IYUV, @@ -255,7 +255,7 @@ static int open(vf_instance_t *vf, char* args){ } #define ST_OFF(f) M_ST_OFF(struct vf_priv_s,f) -static m_option_t vf_opts_fields[] = { +static const m_option_t vf_opts_fields[] = { { "x", ST_OFF(xoff), CONF_TYPE_INT, 0, 0, 0, NULL }, { "y", ST_OFF(yoff), CONF_TYPE_INT, 0, 0, 0, NULL }, { "w", ST_OFF(lw), CONF_TYPE_INT, 0, 0, 0, NULL }, @@ -265,7 +265,7 @@ static m_option_t vf_opts_fields[] = { { NULL, NULL, 0, 0, 0, 0, NULL } }; -static m_struct_t vf_opts = { +static const m_struct_t vf_opts = { "delogo", sizeof(struct vf_priv_s), &vf_priv_dflt, diff --git a/libmpcodecs/vf_denoise3d.c b/libmpcodecs/vf_denoise3d.c index 090f89674a..12bf22f5a2 100644 --- a/libmpcodecs/vf_denoise3d.c +++ b/libmpcodecs/vf_denoise3d.c @@ -51,7 +51,7 @@ struct vf_priv_s { /***************************************************************************/ -static int config(struct vf_instance_s* vf, +static int config(struct vf_instance* vf, int width, int height, int d_width, int d_height, unsigned int flags, unsigned int outfmt){ @@ -64,7 +64,7 @@ static int config(struct vf_instance_s* vf, } -static void uninit(struct vf_instance_s* vf) +static void uninit(struct vf_instance* vf) { free(vf->priv->Line); } @@ -115,7 +115,7 @@ static void deNoise(unsigned char *Frame, // mpi->planes[x] -static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){ +static int put_image(struct vf_instance* vf, mp_image_t *mpi, double pts){ int cw= mpi->w >> mpi->chroma_x_shift; int ch= mpi->h >> mpi->chroma_y_shift; int W = mpi->w, H = mpi->h; @@ -153,7 +153,7 @@ static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){ //===========================================================================// -static int query_format(struct vf_instance_s* vf, unsigned int fmt){ +static int query_format(struct vf_instance* vf, unsigned int fmt){ switch(fmt) { case IMGFMT_YV12: diff --git a/libmpcodecs/vf_detc.c b/libmpcodecs/vf_detc.c index d76e34efd2..4e935cd01b 100644 --- a/libmpcodecs/vf_detc.c +++ b/libmpcodecs/vf_detc.c @@ -267,7 +267,7 @@ static void copy_image(mp_image_t *dmpi, mp_image_t *mpi, int field) } } -static int do_put_image(struct vf_instance_s* vf, mp_image_t *dmpi) +static int do_put_image(struct vf_instance* vf, mp_image_t *dmpi) { struct vf_priv_s *p = vf->priv; int dropflag; @@ -295,7 +295,7 @@ static int do_put_image(struct vf_instance_s* vf, mp_image_t *dmpi) return vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE); } -static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts) +static int put_image(struct vf_instance* vf, mp_image_t *mpi, double pts) { int ret=0; mp_image_t *dmpi; @@ -339,7 +339,7 @@ static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts) return ret; } -static int query_format(struct vf_instance_s* vf, unsigned int fmt) +static int query_format(struct vf_instance* vf, unsigned int fmt) { /* FIXME - figure out which other formats work */ switch (fmt) { @@ -351,14 +351,14 @@ static int query_format(struct vf_instance_s* vf, unsigned int fmt) return 0; } -static int config(struct vf_instance_s* vf, +static int config(struct vf_instance* vf, int width, int height, int d_width, int d_height, unsigned int flags, unsigned int outfmt) { return vf_next_config(vf,width,height,d_width,d_height,flags,outfmt); } -static void uninit(struct vf_instance_s* vf) +static void uninit(struct vf_instance* vf) { free(vf->priv); } diff --git a/libmpcodecs/vf_dint.c b/libmpcodecs/vf_dint.c index b978062d73..62422fb1c4 100644 --- a/libmpcodecs/vf_dint.c +++ b/libmpcodecs/vf_dint.c @@ -24,7 +24,7 @@ struct vf_priv_s { #define MAXROWSIZE 1200 -static int config (struct vf_instance_s* vf, +static int config (struct vf_instance* vf, int width, int height, int d_width, int d_height, unsigned int flags, unsigned int outfmt) { @@ -61,7 +61,7 @@ static int config (struct vf_instance_s* vf, return vf_next_config(vf,width,height,d_width,d_height,flags,outfmt); } -static int put_image (struct vf_instance_s* vf, mp_image_t *mpi, double pts) +static int put_image (struct vf_instance* vf, mp_image_t *mpi, double pts) { char rrow0[MAXROWSIZE]; char rrow1[MAXROWSIZE]; diff --git a/libmpcodecs/vf_divtc.c b/libmpcodecs/vf_divtc.c index 1d55dc1eed..f70d4802ec 100644 --- a/libmpcodecs/vf_divtc.c +++ b/libmpcodecs/vf_divtc.c @@ -206,7 +206,7 @@ static int imgop(int(*planeop)(unsigned char *, unsigned char *, static int match(struct vf_priv_s *p, int *diffs, int phase1, int phase2, double *strength) { - static const int pattern1[]={ -4, 1, 1, 1, 1 }, + const int pattern1[]={ -4, 1, 1, 1, 1 }, pattern2[]={ -2, -3, 4, 4, -3 }, *pattern; int f, m, n, t[5]; @@ -239,7 +239,7 @@ static int match(struct vf_priv_s *p, int *diffs, return m; } -static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts) +static int put_image(struct vf_instance* vf, mp_image_t *mpi, double pts) { mp_image_t *dmpi, *tmpi=0; int n, m, f, newphase; @@ -550,7 +550,7 @@ static int analyze(struct vf_priv_s *p) return 1; } -static int query_format(struct vf_instance_s* vf, unsigned int fmt) +static int query_format(struct vf_instance* vf, unsigned int fmt) { switch(fmt) { @@ -565,7 +565,7 @@ static int query_format(struct vf_instance_s* vf, unsigned int fmt) return 0; } -static void uninit(struct vf_instance_s* vf) +static void uninit(struct vf_instance* vf) { if(vf->priv) { diff --git a/libmpcodecs/vf_down3dright.c b/libmpcodecs/vf_down3dright.c index feb591cb30..3ad2209d33 100644 --- a/libmpcodecs/vf_down3dright.c +++ b/libmpcodecs/vf_down3dright.c @@ -78,7 +78,7 @@ static void toright(unsigned char *dst[3], unsigned char *src[3], } } -static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts) +static int put_image(struct vf_instance* vf, mp_image_t *mpi, double pts) { mp_image_t *dmpi; @@ -95,7 +95,7 @@ static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts) return vf_next_put_image(vf,dmpi, pts); } -static int config(struct vf_instance_s* vf, +static int config(struct vf_instance* vf, int width, int height, int d_width, int d_height, unsigned int flags, unsigned int outfmt) { @@ -105,7 +105,7 @@ static int config(struct vf_instance_s* vf, } -static int query_format(struct vf_instance_s* vf, unsigned int fmt) +static int query_format(struct vf_instance* vf, unsigned int fmt) { /* FIXME - really any YUV 4:2:0 input format should work */ switch (fmt) { @@ -117,7 +117,7 @@ static int query_format(struct vf_instance_s* vf, unsigned int fmt) return 0; } -static void uninit(struct vf_instance_s* vf) +static void uninit(struct vf_instance* vf) { free(vf->priv); } diff --git a/libmpcodecs/vf_dsize.c b/libmpcodecs/vf_dsize.c index 324ddf169a..2ec4acfe3d 100644 --- a/libmpcodecs/vf_dsize.c +++ b/libmpcodecs/vf_dsize.c @@ -17,7 +17,7 @@ struct vf_priv_s { float aspect; }; -static int config(struct vf_instance_s* vf, +static int config(struct vf_instance* vf, int width, int height, int d_width, int d_height, unsigned int flags, unsigned int outfmt) { diff --git a/libmpcodecs/vf_dvbscale.c b/libmpcodecs/vf_dvbscale.c index fedf07046c..d54490d6fc 100644 --- a/libmpcodecs/vf_dvbscale.c +++ b/libmpcodecs/vf_dvbscale.c @@ -16,7 +16,7 @@ struct vf_priv_s { //===========================================================================// -static int config(struct vf_instance_s* vf, +static int config(struct vf_instance* vf, int width, int height, int d_width, int d_height, unsigned int flags, unsigned int outfmt){ diff --git a/libmpcodecs/vf_eq.c b/libmpcodecs/vf_eq.c index ea9efdf30f..d1183fc379 100644 --- a/libmpcodecs/vf_eq.c +++ b/libmpcodecs/vf_eq.c @@ -114,7 +114,7 @@ static void (*process)(unsigned char *dest, int dstride, unsigned char *src, int /* FIXME: add packed yuv version of process */ -static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts) +static int put_image(struct vf_instance* vf, mp_image_t *mpi, double pts) { mp_image_t *dmpi; @@ -143,7 +143,7 @@ static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts) return vf_next_put_image(vf,dmpi, pts); } -static int control(struct vf_instance_s* vf, int request, void* data) +static int control(struct vf_instance* vf, int request, void* data) { vf_equalizer_t *eq; @@ -174,7 +174,7 @@ static int control(struct vf_instance_s* vf, int request, void* data) return vf_next_control(vf, request, data); } -static int query_format(struct vf_instance_s* vf, unsigned int fmt) +static int query_format(struct vf_instance* vf, unsigned int fmt) { switch (fmt) { case IMGFMT_YVU9: @@ -195,7 +195,7 @@ static int query_format(struct vf_instance_s* vf, unsigned int fmt) return 0; } -static void uninit(struct vf_instance_s* vf) +static void uninit(struct vf_instance* vf) { if (vf->priv->buf) free(vf->priv->buf); free(vf->priv); @@ -223,13 +223,13 @@ static int open(vf_instance_t *vf, char* args) } #define ST_OFF(f) M_ST_OFF(struct vf_priv_s,f) -static m_option_t vf_opts_fields[] = { +static const m_option_t vf_opts_fields[] = { {"brightness", ST_OFF(brightness), CONF_TYPE_INT, M_OPT_RANGE,-100 ,100, NULL}, {"contrast", ST_OFF(contrast), CONF_TYPE_INT, M_OPT_RANGE,-100 ,100, NULL}, { NULL, NULL, 0, 0, 0, 0, NULL } }; -static m_struct_t vf_opts = { +static const m_struct_t vf_opts = { "eq", sizeof(struct vf_priv_s), &vf_priv_dflt, diff --git a/libmpcodecs/vf_expand.c b/libmpcodecs/vf_expand.c index 0f25766f09..dec0c524b6 100644 --- a/libmpcodecs/vf_expand.c +++ b/libmpcodecs/vf_expand.c @@ -3,10 +3,12 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <stdbool.h> #include "config.h" #include "mp_msg.h" #include "help_mp.h" +#include "options.h" #include "img_format.h" #include "mp_image.h" @@ -27,12 +29,13 @@ static struct vf_priv_s { int exp_w,exp_h; int exp_x,exp_y; - int osd; + int osd_enabled; double aspect; int round; unsigned char* fb_ptr; int passthrough; int first_slice; + struct osd_state *osd; } const vf_priv_dflt = { -1,-1, -1,-1, @@ -44,13 +47,10 @@ static struct vf_priv_s { 0 }; -extern int opt_screen_size_x; -extern int opt_screen_size_y; - //===========================================================================// #ifdef OSD_SUPPORT -static struct vf_instance_s* vf=NULL; // fixme (needs sub.c changes) +static struct vf_instance* vf=NULL; // fixme (needs sub.c changes) static int orig_w,orig_h; static void remove_func_2(int x0,int y0, int w,int h){ @@ -96,7 +96,7 @@ static void remove_func(int x0,int y0, int w,int h){ } } -static void draw_func(int x0,int y0, int w,int h,unsigned char* src, unsigned char *srca, int stride){ +static void draw_func(void *ctx, int x0,int y0, int w,int h,unsigned char* src, unsigned char *srca, int stride){ unsigned char* dst; if(!vo_osd_changed_flag && vf->dmpi->planes[0]==vf->priv->fb_ptr){ // ok, enough to update the area inside the video, leave the black bands @@ -156,7 +156,7 @@ static void draw_func(int x0,int y0, int w,int h,unsigned char* src, unsigned ch } } -static void draw_osd(struct vf_instance_s* vf_,int w,int h){ +static void draw_osd(struct vf_instance* vf_,int w,int h){ vf=vf_;orig_w=w;orig_h=h; // printf("======================================\n"); if(vf->priv->exp_w!=w || vf->priv->exp_h!=h || @@ -174,10 +174,10 @@ static void draw_osd(struct vf_instance_s* vf_,int w,int h){ remove_func_2(vf->priv->exp_x+w,vf->priv->exp_y,vf->priv->exp_w-w-vf->priv->exp_x,h); } else { // partial clear: - vo_remove_text(vf->priv->exp_w,vf->priv->exp_h,remove_func); + osd_remove_text(vf->priv->osd, vf->priv->exp_w,vf->priv->exp_h,remove_func); } } - vo_draw_text(vf->priv->exp_w,vf->priv->exp_h,draw_func); + osd_draw_text(vf->priv->osd, vf->priv->exp_w,vf->priv->exp_h,draw_func, NULL); // save buffer pointer for double buffering detection - yes, i know it's // ugly method, but note that codecs with DR support does the same... if(vf->dmpi) @@ -187,9 +187,11 @@ static void draw_osd(struct vf_instance_s* vf_,int w,int h){ #endif //===========================================================================// -static int config(struct vf_instance_s* vf, +static int config(struct vf_instance* vf, int width, int height, int d_width, int d_height, - unsigned int flags, unsigned int outfmt){ + unsigned int flags, unsigned int outfmt) +{ + struct MPOpts *opts = vf->opts; if(outfmt == IMGFMT_MPEGPES) { vf->priv->passthrough = 1; return vf_next_config(vf,width,height,d_width,d_height,flags,outfmt); @@ -225,7 +227,7 @@ static int config(struct vf_instance_s* vf, if(vf->priv->exp_y<0 || vf->priv->exp_y+height>vf->priv->exp_h) vf->priv->exp_y=(vf->priv->exp_h-height)/2; vf->priv->fb_ptr=NULL; - if(!opt_screen_size_x && !opt_screen_size_y){ + if(!opts->screen_size_x && !opts->screen_size_y){ d_width=d_width*vf->priv->exp_w/width; d_height=d_height*vf->priv->exp_h/height; } @@ -238,12 +240,12 @@ static int config(struct vf_instance_s* vf, // codec -copy-> expand --DR--> vo // codec -copy-> expand -copy-> vo (worst case) -static void get_image(struct vf_instance_s* vf, mp_image_t *mpi){ +static void get_image(struct vf_instance* vf, mp_image_t *mpi){ // if(mpi->type==MP_IMGTYPE_IPB) return; // not yet working #ifdef OSD_SUPPORT - if(vf->priv->osd && (mpi->flags&MP_IMGFLAG_PRESERVE)){ + if(vf->priv->osd_enabled && (mpi->flags&MP_IMGFLAG_PRESERVE)){ // check if we have to render osd! - vo_update_osd(vf->priv->exp_w, vf->priv->exp_h); + osd_update(vf->priv->osd, vf->priv->exp_w, vf->priv->exp_h); if(vo_osd_check_range_update(vf->priv->exp_x,vf->priv->exp_y, vf->priv->exp_x+mpi->w,vf->priv->exp_y+mpi->h)) return; } @@ -285,7 +287,7 @@ static void get_image(struct vf_instance_s* vf, mp_image_t *mpi){ } } -static void start_slice(struct vf_instance_s* vf, mp_image_t *mpi){ +static void start_slice(struct vf_instance* vf, mp_image_t *mpi){ // printf("start_slice called! flag=%d\n",mpi->flags&MP_IMGFLAG_DRAW_CALLBACK); if(!vf->next->draw_slice){ mpi->flags&=~MP_IMGFLAG_DRAW_CALLBACK; @@ -303,7 +305,7 @@ static void start_slice(struct vf_instance_s* vf, mp_image_t *mpi){ vf->priv->first_slice = 1; } -static void draw_top_blackbar_slice(struct vf_instance_s* vf, +static void draw_top_blackbar_slice(struct vf_instance* vf, unsigned char** src, int* stride, int w,int h, int x, int y){ if(vf->priv->exp_y>0 && y == 0) { vf_next_draw_slice(vf, vf->dmpi->planes, vf->dmpi->stride, @@ -312,7 +314,7 @@ static void draw_top_blackbar_slice(struct vf_instance_s* vf, } -static void draw_bottom_blackbar_slice(struct vf_instance_s* vf, +static void draw_bottom_blackbar_slice(struct vf_instance* vf, unsigned char** src, int* stride, int w,int h, int x, int y){ if(vf->priv->exp_y+vf->h<vf->dmpi->h && y+h == vf->h) { unsigned char *src2[MP_MAX_PLANES]; @@ -332,7 +334,7 @@ static void draw_bottom_blackbar_slice(struct vf_instance_s* vf, } } -static void draw_slice(struct vf_instance_s* vf, +static void draw_slice(struct vf_instance* vf, unsigned char** src, int* stride, int w,int h, int x, int y){ // printf("draw_slice() called %d at %d\n",h,y); @@ -355,7 +357,7 @@ static void draw_slice(struct vf_instance_s* vf, vf->priv->first_slice = 0; } -static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){ +static int put_image(struct vf_instance* vf, mp_image_t *mpi, double pts){ if (vf->priv->passthrough) { mp_image_t *dmpi = vf_get_image(vf->next, IMGFMT_MPEGPES, MP_IMGTYPE_EXPORT, 0, mpi->w, mpi->h); @@ -368,7 +370,7 @@ static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){ if(!vf->dmpi) { mp_msg(MSGT_VFILTER, MSGL_WARN, MSGTR_MPCODECS_FunWhydowegetNULL); return 0; } mpi->priv=NULL; #ifdef OSD_SUPPORT - if(vf->priv->osd) draw_osd(vf,mpi->w,mpi->h); + if(vf->priv->osd_enabled) draw_osd(vf,mpi->w,mpi->h); #endif // we've used DR, so we're ready... if(!(mpi->flags&MP_IMGFLAG_PLANAR)) @@ -403,24 +405,32 @@ static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){ vf->dmpi->planes[1] = mpi->planes[1]; // passthrough rgb8 palette } #ifdef OSD_SUPPORT - if(vf->priv->osd) draw_osd(vf,mpi->w,mpi->h); + if(vf->priv->osd_enabled) draw_osd(vf,mpi->w,mpi->h); #endif return vf_next_put_image(vf,vf->dmpi, pts); } //===========================================================================// -static int control(struct vf_instance_s* vf, int request, void* data){ +static int control(struct vf_instance* vf, int request, void* data){ #ifdef OSD_SUPPORT switch(request){ + case VFCTRL_SET_OSD_OBJ: + vf->priv->osd = data; + break; case VFCTRL_DRAW_OSD: - if(vf->priv->osd) return CONTROL_TRUE; + if(vf->priv->osd_enabled) return CONTROL_TRUE; + break; + case VFCTRL_REDRAW_OSD: + if (vf->priv->osd_enabled) + return false; + break; } #endif return vf_next_control(vf,request,data); } -static int query_format(struct vf_instance_s* vf, unsigned int fmt){ +static int query_format(struct vf_instance* vf, unsigned int fmt){ return vf_next_query_format(vf,fmt); } @@ -437,25 +447,25 @@ static int open(vf_instance_t *vf, char* args){ vf->priv->exp_h, vf->priv->exp_x, vf->priv->exp_y, - vf->priv->osd, + vf->priv->osd_enabled, vf->priv->aspect, vf->priv->round); return 1; } #define ST_OFF(f) M_ST_OFF(struct vf_priv_s,f) -static m_option_t vf_opts_fields[] = { +static const m_option_t vf_opts_fields[] = { {"w", ST_OFF(exp_w), CONF_TYPE_INT, 0, 0 ,0, NULL}, {"h", ST_OFF(exp_h), CONF_TYPE_INT, 0, 0 ,0, NULL}, {"x", ST_OFF(exp_x), CONF_TYPE_INT, M_OPT_MIN, -1, 0, NULL}, {"y", ST_OFF(exp_y), CONF_TYPE_INT, M_OPT_MIN, -1, 0, NULL}, - {"osd", ST_OFF(osd), CONF_TYPE_FLAG, 0 , 0, 1, NULL}, + {"osd", ST_OFF(osd_enabled), CONF_TYPE_FLAG, 0 , 0, 1, NULL}, {"aspect", ST_OFF(aspect), CONF_TYPE_DOUBLE, M_OPT_MIN, 0, 0, NULL}, {"round", ST_OFF(round), CONF_TYPE_INT, M_OPT_MIN, 1, 0, NULL}, { NULL, NULL, 0, 0, 0, 0, NULL } }; -static m_struct_t vf_opts = { +static const m_struct_t vf_opts = { "expand", sizeof(struct vf_priv_s), &vf_priv_dflt, diff --git a/libmpcodecs/vf_field.c b/libmpcodecs/vf_field.c index 00e37f0b59..cbbb7bc104 100644 --- a/libmpcodecs/vf_field.c +++ b/libmpcodecs/vf_field.c @@ -14,13 +14,13 @@ struct vf_priv_s { //===========================================================================// -static int config(struct vf_instance_s* vf, +static int config(struct vf_instance* vf, int width, int height, int d_width, int d_height, unsigned int flags, unsigned int outfmt){ return vf_next_config(vf,width,height/2,d_width,d_height,flags,outfmt); } -static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){ +static int put_image(struct vf_instance* vf, mp_image_t *mpi, double pts){ vf->dmpi=vf_get_image(vf->next,mpi->imgfmt, MP_IMGTYPE_EXPORT, MP_IMGFLAG_ACCEPT_STRIDE, mpi->width, mpi->height/2); @@ -43,7 +43,7 @@ static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){ //===========================================================================// -static void uninit(struct vf_instance_s* vf) +static void uninit(struct vf_instance* vf) { free(vf->priv); } diff --git a/libmpcodecs/vf_fil.c b/libmpcodecs/vf_fil.c index 7648a92adc..5e36c4774d 100644 --- a/libmpcodecs/vf_fil.c +++ b/libmpcodecs/vf_fil.c @@ -17,7 +17,7 @@ struct vf_priv_s { //===========================================================================// -static int config(struct vf_instance_s* vf, +static int config(struct vf_instance* vf, int width, int height, int d_width, int d_height, unsigned int flags, unsigned int outfmt){ int pixel_stride= (width+15)&~15; //FIXME this is ust a guess ... especially for non planar its somewhat bad one @@ -45,7 +45,7 @@ static int config(struct vf_instance_s* vf, (d_width*vf->priv->stridefactor)>>1, 2*d_height/vf->priv->stridefactor, flags, outfmt); } -static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){ +static int put_image(struct vf_instance* vf, mp_image_t *mpi, double pts){ if(mpi->flags&MP_IMGFLAG_DIRECT){ // we've used DR, so we're ready... return vf_next_put_image(vf,(mp_image_t*)mpi->priv, pts); @@ -71,7 +71,7 @@ static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){ //===========================================================================// -static void uninit(struct vf_instance_s* vf) +static void uninit(struct vf_instance* vf) { free(vf->priv); } diff --git a/libmpcodecs/vf_filmdint.c b/libmpcodecs/vf_filmdint.c index 477530e5f1..5427171fbd 100644 --- a/libmpcodecs/vf_filmdint.c +++ b/libmpcodecs/vf_filmdint.c @@ -6,6 +6,7 @@ #include "config.h" #include "mp_msg.h" #include "cpudetect.h" +#include "options.h" #include "img_format.h" #include "mp_image.h" @@ -79,9 +80,6 @@ struct vf_priv_s { static const struct frame_stats ppzs = {PPZ,PPZ,PPZ,PPZ,PPZ,PPZ,PPZ,0,0,9999}; static const struct frame_stats pprs = {PPR,PPR,PPR,PPR,PPR,PPR,PPR,0,0,9999}; -extern int opt_screen_size_x; -extern int opt_screen_size_y; - #ifndef MIN #define MIN(a,b) (((a)<(b))?(a):(b)) #endif @@ -916,7 +914,7 @@ static inline double get_time(void) return tv.tv_sec + tv.tv_usec * 1e-6; } -static void get_image(struct vf_instance_s* vf, mp_image_t *mpi) +static void get_image(struct vf_instance* vf, mp_image_t *mpi) { struct vf_priv_s *p = vf->priv; static unsigned char **planes, planes_idx; @@ -1120,7 +1118,7 @@ find_breaks(struct vf_priv_s *p, struct frame_stats *s) #define ITOC(X) (!(X) ? ' ' : (X) + ((X)>9 ? 'a'-10 : '0')) -static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts) +static int put_image(struct vf_instance* vf, mp_image_t *mpi, double pts) { mp_image_t *dmpi; struct vf_priv_s *p = vf->priv; @@ -1318,7 +1316,7 @@ static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts) return show_fields ? vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE) : 0; } -static int query_format(struct vf_instance_s* vf, unsigned int fmt) +static int query_format(struct vf_instance* vf, unsigned int fmt) { /* FIXME - support more formats */ switch (fmt) { @@ -1333,10 +1331,11 @@ static int query_format(struct vf_instance_s* vf, unsigned int fmt) return 0; } -static int config(struct vf_instance_s* vf, +static int config(struct vf_instance* vf, int width, int height, int d_width, int d_height, unsigned int flags, unsigned int outfmt) { + struct MPOpts *opts = vf->opts; unsigned long cxm = 0; unsigned long cym = 0; struct vf_priv_s *p = vf->priv; @@ -1371,14 +1370,14 @@ static int config(struct vf_instance_s* vf, if (p->crop_x + p->w > width ) p->crop_x = 0; if (p->crop_y + p->h > height) p->crop_y = 0; - if(!opt_screen_size_x && !opt_screen_size_y){ + if(!opts->screen_size_x && !opts->screen_size_y){ d_width = d_width * p->w/width; d_height = d_height * p->h/height; } return vf_next_config(vf, p->w, p->h, d_width, d_height, flags, outfmt); } -static void uninit(struct vf_instance_s* vf) +static void uninit(struct vf_instance* vf) { struct vf_priv_s *p = vf->priv; mp_msg(MSGT_VFILTER, MSGL_INFO, "diff_time: %.3f, merge_time: %.3f, " diff --git a/libmpcodecs/vf_flip.c b/libmpcodecs/vf_flip.c index 8134ff83b6..061c727eb9 100644 --- a/libmpcodecs/vf_flip.c +++ b/libmpcodecs/vf_flip.c @@ -12,14 +12,14 @@ //===========================================================================// -static int config(struct vf_instance_s* vf, +static int config(struct vf_instance* vf, int width, int height, int d_width, int d_height, unsigned int flags, unsigned int outfmt){ flags&=~VOFLAG_FLIPPING; // remove the FLIP flag return vf_next_config(vf,width,height,d_width,d_height,flags,outfmt); } -static void get_image(struct vf_instance_s* vf, mp_image_t *mpi){ +static void get_image(struct vf_instance* vf, mp_image_t *mpi){ if(mpi->flags&MP_IMGFLAG_ACCEPT_STRIDE){ // try full DR ! vf->dmpi=vf_get_image(vf->next,mpi->imgfmt, @@ -41,7 +41,7 @@ static void get_image(struct vf_instance_s* vf, mp_image_t *mpi){ } } -static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){ +static int put_image(struct vf_instance* vf, mp_image_t *mpi, double pts){ if(mpi->flags&MP_IMGFLAG_DIRECT){ // we've used DR, so we're ready... if(!(mpi->flags&MP_IMGFLAG_PLANAR)) diff --git a/libmpcodecs/vf_format.c b/libmpcodecs/vf_format.c index 36280b243c..1a2fa5ce20 100644 --- a/libmpcodecs/vf_format.c +++ b/libmpcodecs/vf_format.c @@ -22,7 +22,7 @@ static struct vf_priv_s { //===========================================================================// -static int query_format(struct vf_instance_s* vf, unsigned int fmt){ +static int query_format(struct vf_instance* vf, unsigned int fmt){ if(fmt==vf->priv->fmt) return vf_next_query_format(vf,fmt); return 0; @@ -74,12 +74,12 @@ static int open(vf_instance_t *vf, char* args){ } #define ST_OFF(f) M_ST_OFF(struct vf_priv_s,f) -static m_option_t vf_opts_fields[] = { +static const m_option_t vf_opts_fields[] = { {"fmt", ST_OFF(fmt), CONF_TYPE_IMGFMT, 0,0 ,0, NULL}, { NULL, NULL, 0, 0, 0, 0, NULL } }; -static m_struct_t vf_opts = { +static const m_struct_t vf_opts = { "format", sizeof(struct vf_priv_s), &vf_priv_dflt, diff --git a/libmpcodecs/vf_framestep.c b/libmpcodecs/vf_framestep.c index 956fe03ae3..c5f93244de 100644 --- a/libmpcodecs/vf_framestep.c +++ b/libmpcodecs/vf_framestep.c @@ -74,7 +74,7 @@ struct vf_priv_s { }; /* Filter handler */ -static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts) +static int put_image(struct vf_instance* vf, mp_image_t *mpi, double pts) { mp_image_t *dmpi; struct vf_priv_s *priv; @@ -131,7 +131,7 @@ static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts) return 0; } -static void uninit(struct vf_instance_s* vf) +static void uninit(struct vf_instance* vf) { /* Free private data */ free(vf->priv); diff --git a/libmpcodecs/vf_fspp.c b/libmpcodecs/vf_fspp.c index cf3aac3768..5ba6188d15 100644 --- a/libmpcodecs/vf_fspp.c +++ b/libmpcodecs/vf_fspp.c @@ -490,7 +490,7 @@ static void filter(struct vf_priv_s *p, uint8_t *dst, uint8_t *src, } } -static int config(struct vf_instance_s* vf, +static int config(struct vf_instance* vf, int width, int height, int d_width, int d_height, unsigned int flags, unsigned int outfmt) { @@ -504,7 +504,7 @@ static int config(struct vf_instance_s* vf, return vf_next_config(vf,width,height,d_width,d_height,flags,outfmt); } -static void get_image(struct vf_instance_s* vf, mp_image_t *mpi) +static void get_image(struct vf_instance* vf, mp_image_t *mpi) { if(mpi->flags&MP_IMGFLAG_PRESERVE) return; // don't change // ok, we can do pp in-place (or pp disabled): @@ -522,7 +522,7 @@ static void get_image(struct vf_instance_s* vf, mp_image_t *mpi) mpi->flags|=MP_IMGFLAG_DIRECT; } -static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts) +static int put_image(struct vf_instance* vf, mp_image_t *mpi, double pts) { mp_image_t *dmpi; if(!(mpi->flags&MP_IMGFLAG_DIRECT)){ @@ -570,7 +570,7 @@ static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts) return vf_next_put_image(vf,dmpi, pts); } -static void uninit(struct vf_instance_s* vf) +static void uninit(struct vf_instance* vf) { if(!vf->priv) return; @@ -589,7 +589,7 @@ static void uninit(struct vf_instance_s* vf) //===========================================================================// -static int query_format(struct vf_instance_s* vf, unsigned int fmt) +static int query_format(struct vf_instance* vf, unsigned int fmt) { switch(fmt){ case IMGFMT_YVU9: @@ -608,7 +608,7 @@ static int query_format(struct vf_instance_s* vf, unsigned int fmt) return 0; } -static int control(struct vf_instance_s* vf, int request, void* data) +static int control(struct vf_instance* vf, int request, void* data) { switch(request){ case VFCTRL_QUERY_MAX_PP_LEVEL: diff --git a/libmpcodecs/vf_geq.c b/libmpcodecs/vf_geq.c index 21da7e2000..d2cbe6554b 100644 --- a/libmpcodecs/vf_geq.c +++ b/libmpcodecs/vf_geq.c @@ -42,13 +42,13 @@ struct vf_priv_s { mp_image_t *mpi; }; -static int config(struct vf_instance_s* vf, +static int config(struct vf_instance* vf, int width, int height, int d_width, int d_height, unsigned int flags, unsigned int outfmt){ return vf_next_config(vf,width,height,d_width,d_height,flags,outfmt); } -static inline double getpix(struct vf_instance_s* vf, double x, double y, int plane){ +static inline double getpix(struct vf_instance* vf, double x, double y, int plane){ int xi, yi; mp_image_t *mpi= vf->priv->mpi; int stride= mpi->stride[plane]; @@ -66,19 +66,19 @@ static inline double getpix(struct vf_instance_s* vf, double x, double y, int pl //FIXME cubic interpolate //FIXME keep the last few frames -static double lum(struct vf_instance_s* vf, double x, double y){ +static double lum(struct vf_instance* vf, double x, double y){ return getpix(vf, x, y, 0); } -static double cb(struct vf_instance_s* vf, double x, double y){ +static double cb(struct vf_instance* vf, double x, double y){ return getpix(vf, x, y, 1); } -static double cr(struct vf_instance_s* vf, double x, double y){ +static double cr(struct vf_instance* vf, double x, double y){ return getpix(vf, x, y, 2); } -static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){ +static int put_image(struct vf_instance* vf, mp_image_t *mpi, double pts){ mp_image_t *dmpi; int x,y, plane; @@ -126,7 +126,7 @@ static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){ return vf_next_put_image(vf,dmpi, pts); } -static void uninit(struct vf_instance_s* vf){ +static void uninit(struct vf_instance* vf){ if(!vf->priv) return; av_free(vf->priv); @@ -151,7 +151,7 @@ static int open(vf_instance_t *vf, char* args){ if (!eq[2][0]) strncpy(eq[2], eq[1], sizeof(eq[0])-1); for(plane=0; plane<3; plane++){ - static const char *const_names[]={ + const char * const const_names[]={ "PI", "E", "X", @@ -163,7 +163,7 @@ static int open(vf_instance_t *vf, char* args){ "SH", NULL }; - static const char *func2_names[]={ + const char * const func2_names[]={ "lum", "cb", "cr", diff --git a/libmpcodecs/vf_halfpack.c b/libmpcodecs/vf_halfpack.c index 44854d7948..15997941f4 100644 --- a/libmpcodecs/vf_halfpack.c +++ b/libmpcodecs/vf_halfpack.c @@ -142,7 +142,7 @@ static void (*halfpack)(unsigned char *dst, unsigned char *src[3], int dststride, int srcstride[3], int w, int h); -static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts) +static int put_image(struct vf_instance* vf, mp_image_t *mpi, double pts) { mp_image_t *dmpi; @@ -166,7 +166,7 @@ static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts) return vf_next_put_image(vf,dmpi, pts); } -static int config(struct vf_instance_s* vf, +static int config(struct vf_instance* vf, int width, int height, int d_width, int d_height, unsigned int flags, unsigned int outfmt) { @@ -175,7 +175,7 @@ static int config(struct vf_instance_s* vf, } -static int query_format(struct vf_instance_s* vf, unsigned int fmt) +static int query_format(struct vf_instance* vf, unsigned int fmt) { /* FIXME - really any YUV 4:2:0 input format should work */ switch (fmt) { @@ -187,7 +187,7 @@ static int query_format(struct vf_instance_s* vf, unsigned int fmt) return 0; } -static void uninit(struct vf_instance_s* vf) +static void uninit(struct vf_instance* vf) { free(vf->priv); } diff --git a/libmpcodecs/vf_harddup.c b/libmpcodecs/vf_harddup.c index 64e3094fda..6bb84143d3 100644 --- a/libmpcodecs/vf_harddup.c +++ b/libmpcodecs/vf_harddup.c @@ -13,7 +13,7 @@ struct vf_priv_s { mp_image_t *last_mpi; }; -static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts) +static int put_image(struct vf_instance* vf, mp_image_t *mpi, double pts) { mp_image_t *dmpi; @@ -34,7 +34,7 @@ static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts) return vf_next_put_image(vf, dmpi, pts); } -static int control(struct vf_instance_s* vf, int request, void* data) +static int control(struct vf_instance* vf, int request, void* data) { switch (request) { case VFCTRL_DUPLICATE_FRAME: @@ -50,7 +50,7 @@ static int control(struct vf_instance_s* vf, int request, void* data) return vf_next_control(vf, request, data); } -static void uninit(struct vf_instance_s* vf) +static void uninit(struct vf_instance* vf) { free(vf->priv); } diff --git a/libmpcodecs/vf_hqdn3d.c b/libmpcodecs/vf_hqdn3d.c index 4e737d73ec..4764c32077 100644 --- a/libmpcodecs/vf_hqdn3d.c +++ b/libmpcodecs/vf_hqdn3d.c @@ -50,14 +50,14 @@ struct vf_priv_s { /***************************************************************************/ -static void uninit(struct vf_instance_s* vf){ +static void uninit(struct vf_instance* vf){ if(vf->priv->Line){free(vf->priv->Line);vf->priv->Line=NULL;} if(vf->priv->Frame[0]){free(vf->priv->Frame[0]);vf->priv->Frame[0]=NULL;} if(vf->priv->Frame[1]){free(vf->priv->Frame[1]);vf->priv->Frame[1]=NULL;} if(vf->priv->Frame[2]){free(vf->priv->Frame[2]);vf->priv->Frame[2]=NULL;} } -static int config(struct vf_instance_s* vf, +static int config(struct vf_instance* vf, int width, int height, int d_width, int d_height, unsigned int flags, unsigned int outfmt){ @@ -208,7 +208,7 @@ static void deNoise(unsigned char *Frame, // mpi->planes[x] } -static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){ +static int put_image(struct vf_instance* vf, mp_image_t *mpi, double pts){ int cw= mpi->w >> mpi->chroma_x_shift; int ch= mpi->h >> mpi->chroma_y_shift; int W = mpi->w, H = mpi->h; @@ -243,7 +243,7 @@ static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){ //===========================================================================// -static int query_format(struct vf_instance_s* vf, unsigned int fmt){ +static int query_format(struct vf_instance* vf, unsigned int fmt){ switch(fmt) { case IMGFMT_YV12: diff --git a/libmpcodecs/vf_hue.c b/libmpcodecs/vf_hue.c index f9f53cfcf6..b10626ddbc 100644 --- a/libmpcodecs/vf_hue.c +++ b/libmpcodecs/vf_hue.c @@ -58,7 +58,7 @@ static void (*process)(uint8_t *udst, uint8_t *vdst, uint8_t *usrc, uint8_t *vsr /* FIXME: add packed yuv version of process */ -static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts) +static int put_image(struct vf_instance* vf, mp_image_t *mpi, double pts) { mp_image_t *dmpi; @@ -92,7 +92,7 @@ static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts) return vf_next_put_image(vf,dmpi, pts); } -static int control(struct vf_instance_s* vf, int request, void* data) +static int control(struct vf_instance* vf, int request, void* data) { vf_equalizer_t *eq; @@ -121,7 +121,7 @@ static int control(struct vf_instance_s* vf, int request, void* data) return vf_next_control(vf, request, data); } -static int query_format(struct vf_instance_s* vf, unsigned int fmt) +static int query_format(struct vf_instance* vf, unsigned int fmt) { switch (fmt) { case IMGFMT_YVU9: @@ -138,7 +138,7 @@ static int query_format(struct vf_instance_s* vf, unsigned int fmt) return 0; } -static void uninit(struct vf_instance_s* vf) +static void uninit(struct vf_instance* vf) { if (vf->priv->buf[0]) free(vf->priv->buf[0]); if (vf->priv->buf[1]) free(vf->priv->buf[1]); @@ -168,13 +168,13 @@ static int open(vf_instance_t *vf, char* args) } #define ST_OFF(f) M_ST_OFF(struct vf_priv_s,f) -static m_option_t vf_opts_fields[] = { +static const m_option_t vf_opts_fields[] = { {"hue", ST_OFF(hue), CONF_TYPE_FLOAT, M_OPT_RANGE,-180.0 ,180.0, NULL}, {"saturation", ST_OFF(saturation), CONF_TYPE_FLOAT, M_OPT_RANGE,-10.0 ,10.0, NULL}, { NULL, NULL, 0, 0, 0, 0, NULL } }; -static m_struct_t vf_opts = { +static const m_struct_t vf_opts = { "hue", sizeof(struct vf_priv_s), &vf_priv_dflt, diff --git a/libmpcodecs/vf_il.c b/libmpcodecs/vf_il.c index 63626aa469..089b14684e 100644 --- a/libmpcodecs/vf_il.c +++ b/libmpcodecs/vf_il.c @@ -79,7 +79,7 @@ static void interleave(uint8_t *dst, uint8_t *src, int w, int h, int dstStride, } } -static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){ +static int put_image(struct vf_instance* vf, mp_image_t *mpi, double pts){ int w; FilterParam *luma = &vf->priv->lumaParam; FilterParam *chroma= &vf->priv->chromaParam; diff --git a/libmpcodecs/vf_ilpack.c b/libmpcodecs/vf_ilpack.c index b9e6bbcb2f..f3ce051535 100644 --- a/libmpcodecs/vf_ilpack.c +++ b/libmpcodecs/vf_ilpack.c @@ -349,7 +349,7 @@ static void ilpack(unsigned char *dst, unsigned char *src[3], } -static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts) +static int put_image(struct vf_instance* vf, mp_image_t *mpi, double pts) { mp_image_t *dmpi; @@ -363,7 +363,7 @@ static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts) return vf_next_put_image(vf,dmpi, pts); } -static int config(struct vf_instance_s* vf, +static int config(struct vf_instance* vf, int width, int height, int d_width, int d_height, unsigned int flags, unsigned int outfmt) { @@ -372,7 +372,7 @@ static int config(struct vf_instance_s* vf, } -static int query_format(struct vf_instance_s* vf, unsigned int fmt) +static int query_format(struct vf_instance* vf, unsigned int fmt) { /* FIXME - really any YUV 4:2:0 input format should work */ switch (fmt) { diff --git a/libmpcodecs/vf_ivtc.c b/libmpcodecs/vf_ivtc.c index 8efd79a225..222b9fec4e 100644 --- a/libmpcodecs/vf_ivtc.c +++ b/libmpcodecs/vf_ivtc.c @@ -408,7 +408,7 @@ static void copy_image(mp_image_t *dmpi, mp_image_t *mpi, int field) } } -static int do_put_image(struct vf_instance_s* vf, mp_image_t *dmpi) +static int do_put_image(struct vf_instance* vf, mp_image_t *dmpi) { struct vf_priv_s *p = vf->priv; int dropflag=0; @@ -437,7 +437,7 @@ static int do_put_image(struct vf_instance_s* vf, mp_image_t *dmpi) return vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE); } -static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts) +static int put_image(struct vf_instance* vf, mp_image_t *mpi, double pts) { int ret=0; struct vf_priv_s *p = vf->priv; @@ -488,7 +488,7 @@ static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts) return ret; } -static int query_format(struct vf_instance_s* vf, unsigned int fmt) +static int query_format(struct vf_instance* vf, unsigned int fmt) { switch (fmt) { case IMGFMT_YV12: @@ -499,7 +499,7 @@ static int query_format(struct vf_instance_s* vf, unsigned int fmt) return 0; } -static void uninit(struct vf_instance_s* vf) +static void uninit(struct vf_instance* vf) { free(vf->priv); } diff --git a/libmpcodecs/vf_kerndeint.c b/libmpcodecs/vf_kerndeint.c index 9fa0df255b..cdc26883eb 100644 --- a/libmpcodecs/vf_kerndeint.c +++ b/libmpcodecs/vf_kerndeint.c @@ -53,7 +53,7 @@ struct vf_priv_s { /***************************************************************************/ -static int config(struct vf_instance_s* vf, +static int config(struct vf_instance* vf, int width, int height, int d_width, int d_height, unsigned int flags, unsigned int outfmt){ @@ -61,7 +61,7 @@ static int config(struct vf_instance_s* vf, } -static void uninit(struct vf_instance_s* vf) +static void uninit(struct vf_instance* vf) { free(vf->priv); } @@ -80,7 +80,7 @@ static inline int IsYUY2(mp_image_t *mpi) #define PLANAR_U 1 #define PLANAR_V 2 -static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){ +static int put_image(struct vf_instance* vf, mp_image_t *mpi, double pts){ int cw= mpi->w >> mpi->chroma_x_shift; int ch= mpi->h >> mpi->chroma_y_shift; int W = mpi->w, H = mpi->h; @@ -284,7 +284,7 @@ static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){ //===========================================================================// -static int query_format(struct vf_instance_s* vf, unsigned int fmt){ +static int query_format(struct vf_instance* vf, unsigned int fmt){ switch(fmt) { case IMGFMT_YV12: @@ -295,7 +295,7 @@ static int query_format(struct vf_instance_s* vf, unsigned int fmt){ return 0; } -static int control(struct vf_instance_s* vf, int request, void* data){ +static int control(struct vf_instance* vf, int request, void* data){ switch (request) { case VFCTRL_GET_DEINTERLACE: diff --git a/libmpcodecs/vf_lavc.c b/libmpcodecs/vf_lavc.c index 7e904b440b..40bd100d73 100644 --- a/libmpcodecs/vf_lavc.c +++ b/libmpcodecs/vf_lavc.c @@ -27,7 +27,7 @@ struct vf_priv_s { //===========================================================================// -static int config(struct vf_instance_s* vf, +static int config(struct vf_instance* vf, int width, int height, int d_width, int d_height, unsigned int flags, unsigned int outfmt){ if(vf_next_query_format(vf,IMGFMT_MPEGPES)<=0) return 0; @@ -69,7 +69,7 @@ static int config(struct vf_instance_s* vf, return vf_next_config(vf,width,height,d_width,d_height,flags,IMGFMT_MPEGPES); } -static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){ +static int put_image(struct vf_instance* vf, mp_image_t *mpi, double pts){ mp_image_t* dmpi; int out_size; AVFrame *pic= vf->priv->pic; @@ -102,7 +102,7 @@ static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){ //===========================================================================// -static int query_format(struct vf_instance_s* vf, unsigned int fmt){ +static int query_format(struct vf_instance* vf, unsigned int fmt){ switch(fmt){ case IMGFMT_YV12: case IMGFMT_I420: diff --git a/libmpcodecs/vf_lavcdeint.c b/libmpcodecs/vf_lavcdeint.c index 27d7f96d0b..ff8aea54dd 100644 --- a/libmpcodecs/vf_lavcdeint.c +++ b/libmpcodecs/vf_lavcdeint.c @@ -70,7 +70,7 @@ imgfmt_to_pixfmt (int imgfmt) static int -config (struct vf_instance_s* vf, +config (struct vf_instance* vf, int width, int height, int d_width, int d_height, unsigned int flags, unsigned int outfmt) { @@ -96,7 +96,7 @@ config (struct vf_instance_s* vf, } static int -put_image (struct vf_instance_s* vf, mp_image_t *mpi, double pts) +put_image (struct vf_instance* vf, mp_image_t *mpi, double pts) { struct vf_priv_s *priv = vf->priv; mp_image_t* dmpi; @@ -133,7 +133,7 @@ put_image (struct vf_instance_s* vf, mp_image_t *mpi, double pts) static int -query_format (struct vf_instance_s* vf, unsigned int fmt) +query_format (struct vf_instance* vf, unsigned int fmt) { if(imgfmt_to_pixfmt(fmt) == -1) return 0; diff --git a/libmpcodecs/vf_mcdeint.c b/libmpcodecs/vf_mcdeint.c index 81b70f58d7..6983aa5163 100644 --- a/libmpcodecs/vf_mcdeint.c +++ b/libmpcodecs/vf_mcdeint.c @@ -184,7 +184,7 @@ static void filter(struct vf_priv_s *p, uint8_t *dst[3], uint8_t *src[3], int ds } -static int config(struct vf_instance_s* vf, +static int config(struct vf_instance* vf, int width, int height, int d_width, int d_height, unsigned int flags, unsigned int outfmt){ int i; @@ -241,7 +241,7 @@ static int config(struct vf_instance_s* vf, return vf_next_config(vf,width,height,d_width,d_height,flags,outfmt); } -static void get_image(struct vf_instance_s* vf, mp_image_t *mpi){ +static void get_image(struct vf_instance* vf, mp_image_t *mpi){ if(mpi->flags&MP_IMGFLAG_PRESERVE) return; // don't change return; //caused problems, dunno why // ok, we can do pp in-place (or pp disabled): @@ -259,7 +259,7 @@ return; //caused problems, dunno why mpi->flags|=MP_IMGFLAG_DIRECT; } -static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){ +static int put_image(struct vf_instance* vf, mp_image_t *mpi, double pts){ mp_image_t *dmpi; if(!(mpi->flags&MP_IMGFLAG_DIRECT)){ @@ -278,7 +278,7 @@ static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){ return vf_next_put_image(vf,dmpi, pts); } -static void uninit(struct vf_instance_s* vf){ +static void uninit(struct vf_instance* vf){ if(!vf->priv) return; #if 0 @@ -300,7 +300,7 @@ static void uninit(struct vf_instance_s* vf){ } //===========================================================================// -static int query_format(struct vf_instance_s* vf, unsigned int fmt){ +static int query_format(struct vf_instance* vf, unsigned int fmt){ switch(fmt){ case IMGFMT_YV12: case IMGFMT_I420: diff --git a/libmpcodecs/vf_mirror.c b/libmpcodecs/vf_mirror.c index f2cf09ee08..5d7d3be80d 100644 --- a/libmpcodecs/vf_mirror.c +++ b/libmpcodecs/vf_mirror.c @@ -65,7 +65,7 @@ static void mirror(unsigned char* dst,unsigned char* src,int dststride,int srcst //===========================================================================// -static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){ +static int put_image(struct vf_instance* vf, mp_image_t *mpi, double pts){ mp_image_t *dmpi; // hope we'll get DR buffer: diff --git a/libmpcodecs/vf_noformat.c b/libmpcodecs/vf_noformat.c index 293e1be4e7..2e97744c54 100644 --- a/libmpcodecs/vf_noformat.c +++ b/libmpcodecs/vf_noformat.c @@ -22,7 +22,7 @@ static struct vf_priv_s { //===========================================================================// -static int query_format(struct vf_instance_s* vf, unsigned int fmt){ +static int query_format(struct vf_instance* vf, unsigned int fmt){ if(fmt!=vf->priv->fmt) return vf_next_query_format(vf,fmt); return 0; @@ -74,12 +74,12 @@ static int open(vf_instance_t *vf, char* args){ } #define ST_OFF(f) M_ST_OFF(struct vf_priv_s,f) -static m_option_t vf_opts_fields[] = { +static const m_option_t vf_opts_fields[] = { {"fmt", ST_OFF(fmt), CONF_TYPE_IMGFMT, 0,0 ,0, NULL}, { NULL, NULL, 0, 0, 0, 0, NULL } }; -static m_struct_t vf_opts = { +static const m_struct_t vf_opts = { "noformat", sizeof(struct vf_priv_s), &vf_priv_dflt, diff --git a/libmpcodecs/vf_noise.c b/libmpcodecs/vf_noise.c index 4704e8fa1b..aab612c2b8 100644 --- a/libmpcodecs/vf_noise.c +++ b/libmpcodecs/vf_noise.c @@ -312,14 +312,14 @@ static void noise(uint8_t *dst, uint8_t *src, int dstStride, int srcStride, int if (fp->shiftptr == 3) fp->shiftptr = 0; } -static int config(struct vf_instance_s* vf, +static int config(struct vf_instance* vf, int width, int height, int d_width, int d_height, unsigned int flags, unsigned int outfmt){ return vf_next_config(vf,width,height,d_width,d_height,flags,outfmt); } -static void get_image(struct vf_instance_s* vf, mp_image_t *mpi){ +static void get_image(struct vf_instance* vf, mp_image_t *mpi){ if(mpi->flags&MP_IMGFLAG_PRESERVE) return; // don't change if(mpi->imgfmt!=vf->priv->outfmt) return; // colorspace differ // ok, we can do pp in-place (or pp disabled): @@ -337,7 +337,7 @@ static void get_image(struct vf_instance_s* vf, mp_image_t *mpi){ mpi->flags|=MP_IMGFLAG_DIRECT; } -static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){ +static int put_image(struct vf_instance* vf, mp_image_t *mpi, double pts){ mp_image_t *dmpi; if(!(mpi->flags&MP_IMGFLAG_DIRECT)){ @@ -366,7 +366,7 @@ static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){ return vf_next_put_image(vf,dmpi, pts); } -static void uninit(struct vf_instance_s* vf){ +static void uninit(struct vf_instance* vf){ if(!vf->priv) return; if(vf->priv->chromaParam.noise) free(vf->priv->chromaParam.noise); @@ -381,7 +381,7 @@ static void uninit(struct vf_instance_s* vf){ //===========================================================================// -static int query_format(struct vf_instance_s* vf, unsigned int fmt){ +static int query_format(struct vf_instance* vf, unsigned int fmt){ switch(fmt) { case IMGFMT_YV12: @@ -416,7 +416,7 @@ static void parse(FilterParam *fp, char* args){ if(fp->strength) initNoise(fp); } -static unsigned int fmt_list[]={ +static const unsigned int fmt_list[]={ IMGFMT_YV12, IMGFMT_I420, IMGFMT_IYUV, diff --git a/libmpcodecs/vf_ow.c b/libmpcodecs/vf_ow.c index 8c1f8f1c48..74f546b082 100644 --- a/libmpcodecs/vf_ow.c +++ b/libmpcodecs/vf_ow.c @@ -210,7 +210,7 @@ static void filter(struct vf_priv_s *p, uint8_t *dst, uint8_t *src, int dst_stri // printf("%f\n", sum/height/width); } -static int config(struct vf_instance_s* vf, int width, int height, int d_width, int d_height, unsigned int flags, unsigned int outfmt){ +static int config(struct vf_instance* vf, int width, int height, int d_width, int d_height, unsigned int flags, unsigned int outfmt){ int h= (height+15)&(~15); int i,j; @@ -223,7 +223,7 @@ static int config(struct vf_instance_s* vf, int width, int height, int d_width, return vf_next_config(vf,width,height,d_width,d_height,flags,outfmt); } -static void get_image(struct vf_instance_s* vf, mp_image_t *mpi){ +static void get_image(struct vf_instance* vf, mp_image_t *mpi){ if(mpi->flags&MP_IMGFLAG_PRESERVE) return; // don't change // ok, we can do pp in-place (or pp disabled): vf->dmpi=vf_get_image(vf->next,mpi->imgfmt, @@ -240,7 +240,7 @@ static void get_image(struct vf_instance_s* vf, mp_image_t *mpi){ mpi->flags|=MP_IMGFLAG_DIRECT; } -static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){ +static int put_image(struct vf_instance* vf, mp_image_t *mpi, double pts){ mp_image_t *dmpi; if(!(mpi->flags&MP_IMGFLAG_DIRECT)){ @@ -261,7 +261,7 @@ static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){ return vf_next_put_image(vf,dmpi, pts); } -static void uninit(struct vf_instance_s* vf){ +static void uninit(struct vf_instance* vf){ int i,j; if(!vf->priv) return; @@ -277,7 +277,7 @@ static void uninit(struct vf_instance_s* vf){ } //===========================================================================// -static int query_format(struct vf_instance_s* vf, unsigned int fmt){ +static int query_format(struct vf_instance* vf, unsigned int fmt){ switch(fmt){ case IMGFMT_YVU9: case IMGFMT_IF09: diff --git a/libmpcodecs/vf_palette.c b/libmpcodecs/vf_palette.c index ece59b2cac..b2105f9487 100644 --- a/libmpcodecs/vf_palette.c +++ b/libmpcodecs/vf_palette.c @@ -19,14 +19,14 @@ // routines are incorrrect. they assume the palette to be of the same // depth as the output, which is incorrect. --Joey -static unsigned int bgr_list[]={ +static const unsigned int bgr_list[]={ IMGFMT_BGR32, IMGFMT_BGR24, // IMGFMT_BGR16, // IMGFMT_BGR15, 0 }; -static unsigned int rgb_list[]={ +static const unsigned int rgb_list[]={ IMGFMT_RGB32, IMGFMT_RGB24, // IMGFMT_RGB16, @@ -36,10 +36,10 @@ static unsigned int rgb_list[]={ static unsigned int gray_pal[256]; -static unsigned int find_best(struct vf_instance_s* vf, unsigned int fmt){ +static unsigned int find_best(struct vf_instance* vf, unsigned int fmt){ unsigned int best=0; int ret; - unsigned int* p; + const unsigned int* p; if(fmt==IMGFMT_BGR8) p=bgr_list; else if(fmt==IMGFMT_RGB8) p=rgb_list; else return 0; @@ -60,7 +60,7 @@ struct vf_priv_s { int pal_msg; }; -static int config(struct vf_instance_s* vf, +static int config(struct vf_instance* vf, int width, int height, int d_width, int d_height, unsigned int flags, unsigned int outfmt){ if (!vf->priv->fmt) @@ -74,7 +74,7 @@ static int config(struct vf_instance_s* vf, return vf_next_config(vf,width,height,d_width,d_height,flags,vf->priv->fmt); } -static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){ +static int put_image(struct vf_instance* vf, mp_image_t *mpi, double pts){ mp_image_t *dmpi; // hope we'll get DR buffer: @@ -158,7 +158,7 @@ static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){ //===========================================================================// -static int query_format(struct vf_instance_s* vf, unsigned int fmt){ +static int query_format(struct vf_instance* vf, unsigned int fmt){ int best=find_best(vf,fmt); if(!best) return 0; // no match return vf->next->query_format(vf->next,best); diff --git a/libmpcodecs/vf_perspective.c b/libmpcodecs/vf_perspective.c index 8ef90d9b5a..fd7fe4885d 100644 --- a/libmpcodecs/vf_perspective.c +++ b/libmpcodecs/vf_perspective.c @@ -102,7 +102,7 @@ static double getCoeff(double d){ return coeff; } -static int config(struct vf_instance_s* vf, +static int config(struct vf_instance* vf, int width, int height, int d_width, int d_height, unsigned int flags, unsigned int outfmt){ int i, j; @@ -129,7 +129,7 @@ static int config(struct vf_instance_s* vf, return vf_next_config(vf,width,height,d_width,d_height,flags,outfmt); } -static void uninit(struct vf_instance_s* vf){ +static void uninit(struct vf_instance* vf){ if(!vf->priv) return; if(vf->priv->pv) free(vf->priv->pv); @@ -258,7 +258,7 @@ static inline void resampleLinear(uint8_t *dst, uint8_t *src, int w, int h, int } } -static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){ +static int put_image(struct vf_instance* vf, mp_image_t *mpi, double pts){ int cw= mpi->w >> mpi->chroma_x_shift; int ch= mpi->h >> mpi->chroma_y_shift; @@ -289,7 +289,7 @@ static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){ //===========================================================================// -static int query_format(struct vf_instance_s* vf, unsigned int fmt){ +static int query_format(struct vf_instance* vf, unsigned int fmt){ switch(fmt) { case IMGFMT_YV12: diff --git a/libmpcodecs/vf_phase.c b/libmpcodecs/vf_phase.c index 348ea4ea45..86d57bfc7f 100644 --- a/libmpcodecs/vf_phase.c +++ b/libmpcodecs/vf_phase.c @@ -178,7 +178,7 @@ static enum mode analyze_plane(unsigned char *old, unsigned char *new, return mode; } -static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts) +static int put_image(struct vf_instance* vf, mp_image_t *mpi, double pts) { mp_image_t *dmpi; int w; @@ -222,7 +222,7 @@ static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts) return vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE); } -static void uninit(struct vf_instance_s* vf) +static void uninit(struct vf_instance* vf) { free(vf->priv->buf[0]); free(vf->priv->buf[1]); diff --git a/libmpcodecs/vf_pp.c b/libmpcodecs/vf_pp.c index c538ee17f4..c910595c4a 100644 --- a/libmpcodecs/vf_pp.c +++ b/libmpcodecs/vf_pp.c @@ -34,7 +34,7 @@ struct vf_priv_s { //===========================================================================// -static int config(struct vf_instance_s* vf, +static int config(struct vf_instance* vf, int width, int height, int d_width, int d_height, unsigned int voflags, unsigned int outfmt){ int flags= @@ -55,7 +55,7 @@ static int config(struct vf_instance_s* vf, return vf_next_config(vf,width,height,d_width,d_height,voflags,outfmt); } -static void uninit(struct vf_instance_s* vf){ +static void uninit(struct vf_instance* vf){ int i; for(i=0; i<=PP_QUALITY_MAX; i++){ if(vf->priv->ppMode[i]) @@ -64,7 +64,7 @@ static void uninit(struct vf_instance_s* vf){ if(vf->priv->context) pp_free_context(vf->priv->context); } -static int query_format(struct vf_instance_s* vf, unsigned int fmt){ +static int query_format(struct vf_instance* vf, unsigned int fmt){ switch(fmt){ case IMGFMT_YV12: case IMGFMT_I420: @@ -77,7 +77,7 @@ static int query_format(struct vf_instance_s* vf, unsigned int fmt){ return 0; } -static int control(struct vf_instance_s* vf, int request, void* data){ +static int control(struct vf_instance* vf, int request, void* data){ switch(request){ case VFCTRL_QUERY_MAX_PP_LEVEL: return PP_QUALITY_MAX; @@ -88,7 +88,7 @@ static int control(struct vf_instance_s* vf, int request, void* data){ return vf_next_control(vf,request,data); } -static void get_image(struct vf_instance_s* vf, mp_image_t *mpi){ +static void get_image(struct vf_instance* vf, mp_image_t *mpi){ if(vf->priv->pp&0xFFFF) return; // non-local filters enabled if((mpi->type==MP_IMGTYPE_IPB || vf->priv->pp) && mpi->flags&MP_IMGFLAG_PRESERVE) return; // don't change @@ -109,7 +109,7 @@ static void get_image(struct vf_instance_s* vf, mp_image_t *mpi){ mpi->flags|=MP_IMGFLAG_DIRECT; } -static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){ +static int put_image(struct vf_instance* vf, mp_image_t *mpi, double pts){ if(!(mpi->flags&MP_IMGFLAG_DIRECT)){ // no DR, so get a new image! hope we'll get DR buffer: vf->dmpi=vf_get_image(vf->next,mpi->imgfmt, @@ -141,7 +141,7 @@ static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){ extern int divx_quality; -static unsigned int fmt_list[]={ +static const unsigned int fmt_list[]={ IMGFMT_YV12, IMGFMT_I420, IMGFMT_IYUV, diff --git a/libmpcodecs/vf_pp7.c b/libmpcodecs/vf_pp7.c index 88b9d9261d..31d6d653b4 100644 --- a/libmpcodecs/vf_pp7.c +++ b/libmpcodecs/vf_pp7.c @@ -344,7 +344,7 @@ static void filter(struct vf_priv_s *p, uint8_t *dst, uint8_t *src, int dst_stri } } -static int config(struct vf_instance_s* vf, +static int config(struct vf_instance* vf, int width, int height, int d_width, int d_height, unsigned int flags, unsigned int outfmt){ int h= (height+16+15)&(~15); @@ -355,7 +355,7 @@ static int config(struct vf_instance_s* vf, return vf_next_config(vf,width,height,d_width,d_height,flags,outfmt); } -static void get_image(struct vf_instance_s* vf, mp_image_t *mpi){ +static void get_image(struct vf_instance* vf, mp_image_t *mpi){ if(mpi->flags&MP_IMGFLAG_PRESERVE) return; // don't change // ok, we can do pp in-place (or pp disabled): vf->dmpi=vf_get_image(vf->next,mpi->imgfmt, @@ -372,7 +372,7 @@ static void get_image(struct vf_instance_s* vf, mp_image_t *mpi){ mpi->flags|=MP_IMGFLAG_DIRECT; } -static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){ +static int put_image(struct vf_instance* vf, mp_image_t *mpi, double pts){ mp_image_t *dmpi; if(mpi->flags&MP_IMGFLAG_DIRECT){ @@ -407,7 +407,7 @@ static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){ return vf_next_put_image(vf,dmpi, pts); } -static void uninit(struct vf_instance_s* vf){ +static void uninit(struct vf_instance* vf){ if(!vf->priv) return; if(vf->priv->src) free(vf->priv->src); @@ -418,7 +418,7 @@ static void uninit(struct vf_instance_s* vf){ } //===========================================================================// -static int query_format(struct vf_instance_s* vf, unsigned int fmt){ +static int query_format(struct vf_instance* vf, unsigned int fmt){ switch(fmt){ case IMGFMT_YVU9: case IMGFMT_IF09: @@ -436,7 +436,7 @@ static int query_format(struct vf_instance_s* vf, unsigned int fmt){ return 0; } -static int control(struct vf_instance_s* vf, int request, void* data){ +static int control(struct vf_instance* vf, int request, void* data){ return vf_next_control(vf,request,data); } diff --git a/libmpcodecs/vf_pullup.c b/libmpcodecs/vf_pullup.c index b1d6cfb393..faf195b613 100644 --- a/libmpcodecs/vf_pullup.c +++ b/libmpcodecs/vf_pullup.c @@ -24,7 +24,7 @@ struct vf_priv_s { char *qbuf; }; -static void init_pullup(struct vf_instance_s* vf, mp_image_t *mpi) +static void init_pullup(struct vf_instance* vf, mp_image_t *mpi) { struct pullup_context *c = vf->priv->ctx; @@ -60,7 +60,7 @@ static void init_pullup(struct vf_instance_s* vf, mp_image_t *mpi) #if 0 -static void get_image(struct vf_instance_s* vf, mp_image_t *mpi) +static void get_image(struct vf_instance* vf, mp_image_t *mpi) { struct pullup_context *c = vf->priv->ctx; struct pullup_buffer *b; @@ -86,7 +86,7 @@ static void get_image(struct vf_instance_s* vf, mp_image_t *mpi) } #endif -static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts) +static int put_image(struct vf_instance* vf, mp_image_t *mpi, double pts) { struct pullup_context *c = vf->priv->ctx; struct pullup_buffer *b; @@ -236,7 +236,7 @@ static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts) return ret; } -static int query_format(struct vf_instance_s* vf, unsigned int fmt) +static int query_format(struct vf_instance* vf, unsigned int fmt) { /* FIXME - support more formats */ switch (fmt) { @@ -248,7 +248,7 @@ static int query_format(struct vf_instance_s* vf, unsigned int fmt) return 0; } -static int config(struct vf_instance_s* vf, +static int config(struct vf_instance* vf, int width, int height, int d_width, int d_height, unsigned int flags, unsigned int outfmt) { @@ -256,7 +256,7 @@ static int config(struct vf_instance_s* vf, return vf_next_config(vf, width, height, d_width, d_height, flags, outfmt); } -static void uninit(struct vf_instance_s* vf) +static void uninit(struct vf_instance* vf) { pullup_free_context(vf->priv->ctx); free(vf->priv); diff --git a/libmpcodecs/vf_qp.c b/libmpcodecs/vf_qp.c index bbce77e5b0..98aeab7535 100644 --- a/libmpcodecs/vf_qp.c +++ b/libmpcodecs/vf_qp.c @@ -48,7 +48,7 @@ struct vf_priv_s { int qp_stride; }; -static int config(struct vf_instance_s* vf, +static int config(struct vf_instance* vf, int width, int height, int d_width, int d_height, unsigned int flags, unsigned int outfmt){ int h= (height+15)>>4; @@ -65,7 +65,7 @@ static int config(struct vf_instance_s* vf, i, 0 }; - static const char *const_names[]={ + const char * const const_names[]={ "PI", "E", "known", @@ -82,7 +82,7 @@ static int config(struct vf_instance_s* vf, return vf_next_config(vf,width,height,d_width,d_height,flags,outfmt); } -static void get_image(struct vf_instance_s* vf, mp_image_t *mpi){ +static void get_image(struct vf_instance* vf, mp_image_t *mpi){ if(mpi->flags&MP_IMGFLAG_PRESERVE) return; // don't change // ok, we can do pp in-place (or pp disabled): vf->dmpi=vf_get_image(vf->next,mpi->imgfmt, @@ -99,7 +99,7 @@ static void get_image(struct vf_instance_s* vf, mp_image_t *mpi){ mpi->flags|=MP_IMGFLAG_DIRECT; } -static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){ +static int put_image(struct vf_instance* vf, mp_image_t *mpi, double pts){ mp_image_t *dmpi; int x,y; @@ -142,7 +142,7 @@ static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){ return vf_next_put_image(vf,dmpi, pts); } -static void uninit(struct vf_instance_s* vf){ +static void uninit(struct vf_instance* vf){ if(!vf->priv) return; if(vf->priv->qp) av_free(vf->priv->qp); diff --git a/libmpcodecs/vf_rectangle.c b/libmpcodecs/vf_rectangle.c index 5a18869c80..221f9dbe8e 100644 --- a/libmpcodecs/vf_rectangle.c +++ b/libmpcodecs/vf_rectangle.c @@ -13,7 +13,7 @@ struct vf_priv_s { }; static int -config(struct vf_instance_s* vf, +config(struct vf_instance* vf, int width, int height, int d_width, int d_height, unsigned int flags, unsigned int outfmt) { @@ -34,7 +34,7 @@ config(struct vf_instance_s* vf, } static int -control(struct vf_instance_s* vf, int request, void *data) +control(struct vf_instance* vf, int request, void *data) { const int *const tmp = data; switch(request){ @@ -65,7 +65,7 @@ control(struct vf_instance_s* vf, int request, void *data) return 0; } static int -put_image(struct vf_instance_s* vf, mp_image_t* mpi, double pts){ +put_image(struct vf_instance* vf, mp_image_t* mpi, double pts){ mp_image_t* dmpi; unsigned int bpp = mpi->bpp / 8; int x, y, w, h; diff --git a/libmpcodecs/vf_remove_logo.c b/libmpcodecs/vf_remove_logo.c index 086613a0ec..919c17455d 100644 --- a/libmpcodecs/vf_remove_logo.c +++ b/libmpcodecs/vf_remove_logo.c @@ -670,7 +670,7 @@ static pgm_structure * generate_half_size_image(vf_instance_t * vf, pgm_structur /** * \brief Checks if YV12 is supported by the next filter. */ -static unsigned int find_best(struct vf_instance_s* vf){ +static unsigned int find_best(struct vf_instance* vf){ int is_format_okay = vf->next->query_format(vf->next, IMGFMT_YV12); if ((is_format_okay & VFCAP_CSP_SUPPORTED_BY_HW) || (is_format_okay & VFCAP_CSP_SUPPORTED)) return IMGFMT_YV12; @@ -683,7 +683,7 @@ static unsigned int find_best(struct vf_instance_s* vf){ /** * \brief Configure the filter and call the next filter's config function. */ -static int config(struct vf_instance_s* vf, int width, int height, int d_width, int d_height, unsigned int flags, unsigned int outfmt) +static int config(struct vf_instance* vf, int width, int height, int d_width, int d_height, unsigned int flags, unsigned int outfmt) { if(!(((vf_priv_s *)vf->priv)->fmt=find_best(vf))) return 0; @@ -764,7 +764,7 @@ static void convert_yv12(const vf_instance_t * const vf, const char * const sour * filter, has the logo removed by the filter, and is then sent to the next * filter. */ -static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){ +static int put_image(struct vf_instance* vf, mp_image_t *mpi, double pts){ mp_image_t *dmpi; dmpi=vf_get_image(vf->next,((vf_priv_s *)vf->priv)->fmt, @@ -811,7 +811,7 @@ static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){ /** * \brief Checks to see if the next filter accepts YV12 images. */ -static int query_format(struct vf_instance_s * vf, unsigned int fmt) +static int query_format(struct vf_instance * vf, unsigned int fmt) { if (fmt == IMGFMT_YV12) return vf->next->query_format(vf->next, IMGFMT_YV12); @@ -877,7 +877,7 @@ static int open(vf_instance_t * vf, char * args) * * This is called at exit-time. */ -void uninit(vf_instance_t * vf) +static void uninit(vf_instance_t * vf) { /* Destroy our masks and images. */ destroy_pgm(((vf_priv_s *)vf->priv)->filter); diff --git a/libmpcodecs/vf_rgb2bgr.c b/libmpcodecs/vf_rgb2bgr.c index 9e372fc719..bf00ab7f07 100644 --- a/libmpcodecs/vf_rgb2bgr.c +++ b/libmpcodecs/vf_rgb2bgr.c @@ -36,14 +36,14 @@ static unsigned int getfmt(unsigned int outfmt,int forced){ return 0; } -static int config(struct vf_instance_s* vf, +static int config(struct vf_instance* vf, int width, int height, int d_width, int d_height, unsigned int flags, unsigned int outfmt){ vf->priv->fmt=getfmt(outfmt,vf->priv->forced); return vf_next_config(vf,width,height,d_width,d_height,flags,vf->priv->fmt); } -static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){ +static int put_image(struct vf_instance* vf, mp_image_t *mpi, double pts){ mp_image_t *dmpi; // hope we'll get DR buffer: @@ -76,7 +76,7 @@ static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){ //===========================================================================// -static int query_format(struct vf_instance_s* vf, unsigned int outfmt){ +static int query_format(struct vf_instance* vf, unsigned int outfmt){ unsigned int fmt=getfmt(outfmt,vf->priv->forced); if(!fmt) return 0; return vf_next_query_format(vf,fmt) & (~VFCAP_CSP_SUPPORTED_BY_HW); diff --git a/libmpcodecs/vf_rgbtest.c b/libmpcodecs/vf_rgbtest.c index 4351956da2..c9f134ad6a 100644 --- a/libmpcodecs/vf_rgbtest.c +++ b/libmpcodecs/vf_rgbtest.c @@ -77,7 +77,7 @@ static void put_pixel(uint8_t *buf, int x, int y, int stride, int r, int g, int } } -static int config(struct vf_instance_s* vf, +static int config(struct vf_instance* vf, int width, int height, int d_width, int d_height, unsigned int flags, unsigned int outfmt){ if (vf->priv->w > 0) { d_width = width = vf->priv->w; } @@ -87,7 +87,7 @@ static int config(struct vf_instance_s* vf, return vf_next_config(vf,width,height,d_width,d_height,flags,vf->priv->fmt); } -static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){ +static int put_image(struct vf_instance* vf, mp_image_t *mpi, double pts){ mp_image_t *dmpi; int x, y; int w = vf->priv->w > 0 ? vf->priv->w : mpi->w; @@ -116,7 +116,7 @@ static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){ //===========================================================================// -static int query_format(struct vf_instance_s* vf, unsigned int outfmt){ +static int query_format(struct vf_instance* vf, unsigned int outfmt){ unsigned int fmt=getfmt(outfmt); if(!fmt) return 0; return vf_next_query_format(vf,fmt) & (~VFCAP_CSP_SUPPORTED_BY_HW); diff --git a/libmpcodecs/vf_rotate.c b/libmpcodecs/vf_rotate.c index 0d1a23d9ac..24015d250b 100644 --- a/libmpcodecs/vf_rotate.c +++ b/libmpcodecs/vf_rotate.c @@ -50,7 +50,7 @@ static void rotate(unsigned char* dst,unsigned char* src,int dststride,int srcst //===========================================================================// -static int config(struct vf_instance_s* vf, +static int config(struct vf_instance* vf, int width, int height, int d_width, int d_height, unsigned int flags, unsigned int outfmt){ if (vf->priv->direction & 4) { @@ -66,7 +66,7 @@ static int config(struct vf_instance_s* vf, return vf_next_config(vf,height,width,d_height,d_width,flags,outfmt); } -static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){ +static int put_image(struct vf_instance* vf, mp_image_t *mpi, double pts){ mp_image_t *dmpi; // hope we'll get DR buffer: @@ -96,7 +96,7 @@ static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){ //===========================================================================// -static int query_format(struct vf_instance_s* vf, unsigned int fmt){ +static int query_format(struct vf_instance* vf, unsigned int fmt){ if(IMGFMT_IS_RGB(fmt) || IMGFMT_IS_BGR(fmt)) return vf_next_query_format(vf, fmt); // we can support only symmetric (chroma_x_shift==chroma_y_shift) YUV formats: switch(fmt) { diff --git a/libmpcodecs/vf_sab.c b/libmpcodecs/vf_sab.c index 676b4bf4b0..61a5a7bc32 100644 --- a/libmpcodecs/vf_sab.c +++ b/libmpcodecs/vf_sab.c @@ -135,7 +135,7 @@ static int allocStuff(FilterParam *f, int width, int height){ return 0; } -static int config(struct vf_instance_s* vf, +static int config(struct vf_instance* vf, int width, int height, int d_width, int d_height, unsigned int flags, unsigned int outfmt){ @@ -160,7 +160,7 @@ static void freeBuffers(FilterParam *f){ f->distCoeff=NULL; } -static void uninit(struct vf_instance_s* vf){ +static void uninit(struct vf_instance* vf){ if(!vf->priv) return; freeBuffers(&vf->priv->luma); @@ -238,7 +238,7 @@ if((x/32)&1){ } } -static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){ +static int put_image(struct vf_instance* vf, mp_image_t *mpi, double pts){ int cw= mpi->w >> mpi->chroma_x_shift; int ch= mpi->h >> mpi->chroma_y_shift; @@ -257,7 +257,7 @@ static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){ //===========================================================================// -static int query_format(struct vf_instance_s* vf, unsigned int fmt){ +static int query_format(struct vf_instance* vf, unsigned int fmt){ switch(fmt) { case IMGFMT_YV12: diff --git a/libmpcodecs/vf_scale.c b/libmpcodecs/vf_scale.c index b6c683c430..fd1c6ee7f3 100644 --- a/libmpcodecs/vf_scale.c +++ b/libmpcodecs/vf_scale.c @@ -6,6 +6,7 @@ #include "config.h" #include "mp_msg.h" #include "cpudetect.h" +#include "options.h" #include "img_format.h" #include "mp_image.h" @@ -41,15 +42,11 @@ static struct vf_priv_s { NULL }; -extern int opt_screen_size_x; -extern int opt_screen_size_y; -extern float screen_size_xy; - //===========================================================================// void sws_getFlagsAndFilterFromCmdLine(int *flags, SwsFilter **srcFilterParam, SwsFilter **dstFilterParam); -static unsigned int outfmt_list[]={ +static const unsigned int outfmt_list[]={ // YUV: IMGFMT_444P, IMGFMT_422P, @@ -109,9 +106,10 @@ static unsigned int find_best_out(vf_instance_t *vf){ return best; } -static int config(struct vf_instance_s* vf, +static int config(struct vf_instance* vf, int width, int height, int d_width, int d_height, unsigned int flags, unsigned int outfmt){ + struct MPOpts *opts = vf->opts; unsigned int best=find_best_out(vf); int vo_flags; int int_sws_flags=0; @@ -293,7 +291,8 @@ static int config(struct vf_instance_s* vf, break; } } - if(!opt_screen_size_x && !opt_screen_size_y && !(screen_size_xy >= 0.001)){ + if (!opts->screen_size_x && !opts->screen_size_y + && !(opts->screen_size_xy >= 0.001)) { // Compute new d_width and d_height, preserving aspect // while ensuring that both are >= output size in pixels. if (vf->priv->h * d_width > vf->priv->w * d_height) { @@ -309,7 +308,7 @@ static int config(struct vf_instance_s* vf, return vf_next_config(vf,vf->priv->w,vf->priv->h,d_width,d_height,flags,best); } -static void start_slice(struct vf_instance_s* vf, mp_image_t *mpi){ +static void start_slice(struct vf_instance* vf, mp_image_t *mpi){ // printf("start_slice called! flag=%d\n",mpi->flags&MP_IMGFLAG_DRAW_CALLBACK); if(!(mpi->flags&MP_IMGFLAG_DRAW_CALLBACK)) return; // shouldn't happen // they want slices!!! allocate the buffer. @@ -349,7 +348,7 @@ static void scale(struct SwsContext *sws1, struct SwsContext *sws2, uint8_t *src } } -static void draw_slice(struct vf_instance_s* vf, +static void draw_slice(struct vf_instance* vf, unsigned char** src, int* stride, int w,int h, int x, int y){ mp_image_t *dmpi=vf->dmpi; if(!dmpi){ @@ -360,7 +359,7 @@ static void draw_slice(struct vf_instance_s* vf, scale(vf->priv->ctx, vf->priv->ctx2, src, stride, y, h, dmpi->planes, dmpi->stride, vf->priv->interlaced); } -static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){ +static int put_image(struct vf_instance* vf, mp_image_t *mpi, double pts){ mp_image_t *dmpi=mpi->priv; // printf("vf_scale::put_image(): processing whole frame! dmpi=%p flag=%d\n", @@ -387,7 +386,7 @@ static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){ return vf_next_put_image(vf,dmpi, pts); } -static int control(struct vf_instance_s* vf, int request, void* data){ +static int control(struct vf_instance* vf, int request, void* data){ int *table; int *inv_table; int r; @@ -450,7 +449,7 @@ static int control(struct vf_instance_s* vf, int request, void* data){ // supported Input formats: YV12, I420, IYUV, YUY2, UYVY, BGR32, BGR24, BGR16, BGR15, RGB32, RGB24, Y8, Y800 -static int query_format(struct vf_instance_s* vf, unsigned int fmt){ +static int query_format(struct vf_instance* vf, unsigned int fmt){ switch(fmt){ case IMGFMT_YV12: case IMGFMT_I420: @@ -489,7 +488,7 @@ static int query_format(struct vf_instance_s* vf, unsigned int fmt){ return 0; // nomatching in-fmt } -static void uninit(struct vf_instance_s *vf){ +static void uninit(struct vf_instance *vf){ if(vf->priv->ctx) sws_freeContext(vf->priv->ctx); if(vf->priv->ctx2) sws_freeContext(vf->priv->ctx2); if(vf->priv->palette) free(vf->priv->palette); @@ -610,7 +609,7 @@ struct SwsContext *sws_getContextFromCmdLine(int srcW, int srcH, int srcFormat, } /// An example of presets usage -static struct size_preset { +static const struct size_preset { char* name; int w, h; } vf_size_presets_defs[] = { @@ -625,21 +624,21 @@ static struct size_preset { }; #define ST_OFF(f) M_ST_OFF(struct size_preset,f) -static m_option_t vf_size_preset_fields[] = { +static const m_option_t vf_size_preset_fields[] = { {"w", ST_OFF(w), CONF_TYPE_INT, M_OPT_MIN,1 ,0, NULL}, {"h", ST_OFF(h), CONF_TYPE_INT, M_OPT_MIN,1 ,0, NULL}, { NULL, NULL, 0, 0, 0, 0, NULL } }; -static m_struct_t vf_size_preset = { +static const m_struct_t vf_size_preset = { "scale_size_preset", sizeof(struct size_preset), NULL, vf_size_preset_fields }; -static m_struct_t vf_opts; -static m_obj_presets_t size_preset = { +static const m_struct_t vf_opts; +static const m_obj_presets_t size_preset = { &vf_size_preset, // Input struct desc &vf_opts, // Output struct desc vf_size_presets_defs, // The list of presets @@ -649,7 +648,7 @@ static m_obj_presets_t size_preset = { /// Now the options #undef ST_OFF #define ST_OFF(f) M_ST_OFF(struct vf_priv_s,f) -static m_option_t vf_opts_fields[] = { +static const m_option_t vf_opts_fields[] = { {"w", ST_OFF(w), CONF_TYPE_INT, M_OPT_MIN,-11,0, NULL}, {"h", ST_OFF(h), CONF_TYPE_INT, M_OPT_MIN,-11,0, NULL}, {"interlaced", ST_OFF(interlaced), CONF_TYPE_INT, M_OPT_RANGE, 0, 1, NULL}, @@ -664,7 +663,7 @@ static m_option_t vf_opts_fields[] = { { NULL, NULL, 0, 0, 0, 0, NULL } }; -static m_struct_t vf_opts = { +static const m_struct_t vf_opts = { "scale", sizeof(struct vf_priv_s), &vf_priv_dflt, diff --git a/libmpcodecs/vf_screenshot.c b/libmpcodecs/vf_screenshot.c index 9d6b48d5bf..8471285345 100644 --- a/libmpcodecs/vf_screenshot.c +++ b/libmpcodecs/vf_screenshot.c @@ -40,7 +40,7 @@ struct vf_priv_s { //===========================================================================// -static int config(struct vf_instance_s* vf, +static int config(struct vf_instance* vf, int width, int height, int d_width, int d_height, unsigned int flags, unsigned int outfmt) { @@ -121,7 +121,7 @@ static void scale_image(struct vf_priv_s* priv, mp_image_t *mpi) sws_scale_ordered(priv->ctx, mpi->planes, mpi->stride, 0, priv->dh, dst, dst_stride); } -static void start_slice(struct vf_instance_s* vf, mp_image_t *mpi) +static void start_slice(struct vf_instance* vf, mp_image_t *mpi) { vf->dmpi=vf_get_image(vf->next,mpi->imgfmt, mpi->type, mpi->flags, mpi->width, mpi->height); @@ -133,7 +133,7 @@ static void start_slice(struct vf_instance_s* vf, mp_image_t *mpi) } -static void draw_slice(struct vf_instance_s* vf, unsigned char** src, +static void draw_slice(struct vf_instance* vf, unsigned char** src, int* stride, int w,int h, int x, int y) { if (vf->priv->store_slices) { @@ -148,7 +148,7 @@ static void draw_slice(struct vf_instance_s* vf, unsigned char** src, vf_next_draw_slice(vf,src,stride,w,h,x,y); } -static void get_image(struct vf_instance_s* vf, mp_image_t *mpi) +static void get_image(struct vf_instance* vf, mp_image_t *mpi) { // FIXME: should vf.c really call get_image when using slices?? if (mpi->flags & MP_IMGFLAG_DRAW_CALLBACK) @@ -171,7 +171,7 @@ static void get_image(struct vf_instance_s* vf, mp_image_t *mpi) mpi->priv=(void*)vf->dmpi; } -static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts) +static int put_image(struct vf_instance* vf, mp_image_t *mpi, double pts) { mp_image_t *dmpi = (mp_image_t *)mpi->priv; @@ -208,7 +208,7 @@ static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts) return vf_next_put_image(vf, dmpi, pts); } -int control (vf_instance_t *vf, int request, void *data) +static int control (vf_instance_t *vf, int request, void *data) { /** data contains an integer argument * 0: take screenshot with the next frame @@ -232,7 +232,7 @@ int control (vf_instance_t *vf, int request, void *data) //===========================================================================// -static int query_format(struct vf_instance_s* vf, unsigned int fmt) +static int query_format(struct vf_instance* vf, unsigned int fmt) { switch(fmt){ case IMGFMT_YV12: diff --git a/libmpcodecs/vf_smartblur.c b/libmpcodecs/vf_smartblur.c index 1ca1cbac26..82265416cc 100644 --- a/libmpcodecs/vf_smartblur.c +++ b/libmpcodecs/vf_smartblur.c @@ -100,7 +100,7 @@ static int allocStuff(FilterParam *f, int width, int height){ return 0; } -static int config(struct vf_instance_s* vf, +static int config(struct vf_instance* vf, int width, int height, int d_width, int d_height, unsigned int flags, unsigned int outfmt){ @@ -119,7 +119,7 @@ static void freeBuffers(FilterParam *f){ f->filterContext=NULL; } -static void uninit(struct vf_instance_s* vf){ +static void uninit(struct vf_instance* vf){ if(!vf->priv) return; freeBuffers(&vf->priv->luma); @@ -186,7 +186,7 @@ static inline void blur(uint8_t *dst, uint8_t *src, int w, int h, int dstStride, } } -static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){ +static int put_image(struct vf_instance* vf, mp_image_t *mpi, double pts){ int cw= mpi->w >> mpi->chroma_x_shift; int ch= mpi->h >> mpi->chroma_y_shift; FilterParam *f= &vf->priv; @@ -207,7 +207,7 @@ static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){ //===========================================================================// -static int query_format(struct vf_instance_s* vf, unsigned int fmt){ +static int query_format(struct vf_instance* vf, unsigned int fmt){ switch(fmt) { case IMGFMT_YV12: diff --git a/libmpcodecs/vf_softpulldown.c b/libmpcodecs/vf_softpulldown.c index 30bb405eb5..c8f1c4cf79 100644 --- a/libmpcodecs/vf_softpulldown.c +++ b/libmpcodecs/vf_softpulldown.c @@ -17,7 +17,7 @@ struct vf_priv_s { long long out; }; -static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts) +static int put_image(struct vf_instance* vf, mp_image_t *mpi, double pts) { mp_image_t *dmpi; int ret = 0; @@ -111,14 +111,14 @@ static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts) return ret; } -static int config(struct vf_instance_s* vf, +static int config(struct vf_instance* vf, int width, int height, int d_width, int d_height, unsigned int flags, unsigned int outfmt) { return vf_next_config(vf,width,height,d_width,d_height,flags,outfmt); } -static void uninit(struct vf_instance_s* vf) +static void uninit(struct vf_instance* vf) { mp_msg(MSGT_VFILTER, MSGL_INFO, "softpulldown: %lld frames in, %lld frames out\n", vf->priv->in, vf->priv->out); free(vf->priv); diff --git a/libmpcodecs/vf_softskip.c b/libmpcodecs/vf_softskip.c index 89727906ce..62fd0ce5ae 100644 --- a/libmpcodecs/vf_softskip.c +++ b/libmpcodecs/vf_softskip.c @@ -13,7 +13,7 @@ struct vf_priv_s { int skipflag; }; -static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts) +static int put_image(struct vf_instance* vf, mp_image_t *mpi, double pts) { mp_image_t *dmpi; @@ -36,7 +36,7 @@ static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts) return vf_next_put_image(vf, dmpi, pts); } -static int control(struct vf_instance_s* vf, int request, void* data) +static int control(struct vf_instance* vf, int request, void* data) { switch (request) { case VFCTRL_SKIP_NEXT_FRAME: @@ -47,7 +47,7 @@ static int control(struct vf_instance_s* vf, int request, void* data) } #if 0 -static int query_format(struct vf_instance_s* vf, unsigned int fmt) +static int query_format(struct vf_instance* vf, unsigned int fmt) { /* FIXME - figure out which other formats work */ switch (fmt) { @@ -60,7 +60,7 @@ static int query_format(struct vf_instance_s* vf, unsigned int fmt) } #endif -static void uninit(struct vf_instance_s* vf) +static void uninit(struct vf_instance* vf) { free(vf->priv); } diff --git a/libmpcodecs/vf_spp.c b/libmpcodecs/vf_spp.c index f1071bf5d6..aa18534966 100644 --- a/libmpcodecs/vf_spp.c +++ b/libmpcodecs/vf_spp.c @@ -439,7 +439,7 @@ static void filter(struct vf_priv_s *p, uint8_t *dst, uint8_t *src, int dst_stri //FIXME reorder for better caching } -static int config(struct vf_instance_s* vf, +static int config(struct vf_instance* vf, int width, int height, int d_width, int d_height, unsigned int flags, unsigned int outfmt){ int h= (height+16+15)&(~15); @@ -451,7 +451,7 @@ static int config(struct vf_instance_s* vf, return vf_next_config(vf,width,height,d_width,d_height,flags,outfmt); } -static void get_image(struct vf_instance_s* vf, mp_image_t *mpi){ +static void get_image(struct vf_instance* vf, mp_image_t *mpi){ if(mpi->flags&MP_IMGFLAG_PRESERVE) return; // don't change // ok, we can do pp in-place (or pp disabled): vf->dmpi=vf_get_image(vf->next,mpi->imgfmt, @@ -468,7 +468,7 @@ static void get_image(struct vf_instance_s* vf, mp_image_t *mpi){ mpi->flags|=MP_IMGFLAG_DIRECT; } -static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){ +static int put_image(struct vf_instance* vf, mp_image_t *mpi, double pts){ mp_image_t *dmpi; if(!(mpi->flags&MP_IMGFLAG_DIRECT)){ @@ -514,7 +514,7 @@ static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){ return vf_next_put_image(vf,dmpi, pts); } -static void uninit(struct vf_instance_s* vf){ +static void uninit(struct vf_instance* vf){ if(!vf->priv) return; if(vf->priv->temp) free(vf->priv->temp); @@ -531,7 +531,7 @@ static void uninit(struct vf_instance_s* vf){ } //===========================================================================// -static int query_format(struct vf_instance_s* vf, unsigned int fmt){ +static int query_format(struct vf_instance* vf, unsigned int fmt){ switch(fmt){ case IMGFMT_YVU9: case IMGFMT_IF09: @@ -549,7 +549,7 @@ static int query_format(struct vf_instance_s* vf, unsigned int fmt){ return 0; } -static int control(struct vf_instance_s* vf, int request, void* data){ +static int control(struct vf_instance* vf, int request, void* data){ switch(request){ case VFCTRL_QUERY_MAX_PP_LEVEL: return 6; diff --git a/libmpcodecs/vf_swapuv.c b/libmpcodecs/vf_swapuv.c index f9a65ae6b1..d466e2154e 100644 --- a/libmpcodecs/vf_swapuv.c +++ b/libmpcodecs/vf_swapuv.c @@ -38,7 +38,7 @@ //===========================================================================// -static void get_image(struct vf_instance_s* vf, mp_image_t *mpi){ +static void get_image(struct vf_instance* vf, mp_image_t *mpi){ mp_image_t *dmpi= vf_get_image(vf->next, mpi->imgfmt, mpi->type, mpi->flags, mpi->w, mpi->h); @@ -54,7 +54,7 @@ static void get_image(struct vf_instance_s* vf, mp_image_t *mpi){ mpi->priv=(void*)dmpi; } -static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){ +static int put_image(struct vf_instance* vf, mp_image_t *mpi, double pts){ mp_image_t *dmpi; if(mpi->flags&MP_IMGFLAG_DIRECT){ @@ -78,7 +78,7 @@ static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){ //===========================================================================// -static int query_format(struct vf_instance_s* vf, unsigned int fmt){ +static int query_format(struct vf_instance* vf, unsigned int fmt){ switch(fmt) { case IMGFMT_YV12: diff --git a/libmpcodecs/vf_telecine.c b/libmpcodecs/vf_telecine.c index 3ce136e5bf..b524f395b6 100644 --- a/libmpcodecs/vf_telecine.c +++ b/libmpcodecs/vf_telecine.c @@ -15,7 +15,7 @@ struct vf_priv_s { int frame; }; -static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts) +static int put_image(struct vf_instance* vf, mp_image_t *mpi, double pts) { mp_image_t *dmpi; int ret; @@ -88,7 +88,7 @@ static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts) } #if 0 -static int query_format(struct vf_instance_s* vf, unsigned int fmt) +static int query_format(struct vf_instance* vf, unsigned int fmt) { /* FIXME - figure out which other formats work */ switch (fmt) { @@ -100,7 +100,7 @@ static int query_format(struct vf_instance_s* vf, unsigned int fmt) return 0; } -static int config(struct vf_instance_s* vf, +static int config(struct vf_instance* vf, int width, int height, int d_width, int d_height, unsigned int flags, unsigned int outfmt) { @@ -108,7 +108,7 @@ static int config(struct vf_instance_s* vf, } #endif -static void uninit(struct vf_instance_s* vf) +static void uninit(struct vf_instance* vf) { free(vf->priv); } diff --git a/libmpcodecs/vf_test.c b/libmpcodecs/vf_test.c index 1f51011e57..a2ccd611e3 100644 --- a/libmpcodecs/vf_test.c +++ b/libmpcodecs/vf_test.c @@ -47,7 +47,7 @@ struct vf_priv_s { int frame_num; }; -static int config(struct vf_instance_s* vf, +static int config(struct vf_instance* vf, int width, int height, int d_width, int d_height, unsigned int flags, unsigned int outfmt){ @@ -269,7 +269,7 @@ static void ring2Test(uint8_t *dst, int stride, int off) } } -static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){ +static int put_image(struct vf_instance* vf, mp_image_t *mpi, double pts){ mp_image_t *dmpi; int frame= vf->priv->frame_num; @@ -307,7 +307,7 @@ static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){ //===========================================================================// -static int query_format(struct vf_instance_s* vf, unsigned int fmt){ +static int query_format(struct vf_instance* vf, unsigned int fmt){ return vf_next_query_format(vf,IMGFMT_YV12) & (~VFCAP_CSP_SUPPORTED_BY_HW); } diff --git a/libmpcodecs/vf_tfields.c b/libmpcodecs/vf_tfields.c index 1118484cc5..3203054d85 100644 --- a/libmpcodecs/vf_tfields.c +++ b/libmpcodecs/vf_tfields.c @@ -3,6 +3,7 @@ #include <string.h> #include "config.h" +#include "options.h" #include "mp_msg.h" #include "cpudetect.h" @@ -299,10 +300,9 @@ static void qpel_4tap_C(unsigned char *d, unsigned char *s, int w, int h, int ds static void (*qpel_li)(unsigned char *d, unsigned char *s, int w, int h, int ds, int ss, int up); static void (*qpel_4tap)(unsigned char *d, unsigned char *s, int w, int h, int ds, int ss, int up); -static int continue_buffered_image(struct vf_instance_s *); -extern int correct_pts; +static int continue_buffered_image(struct vf_instance *); -static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts) +static int put_image(struct vf_instance* vf, mp_image_t *mpi, double pts) { vf->priv->buffered_mpi = mpi; vf->priv->buffered_pts = pts; @@ -310,7 +310,9 @@ static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts) return continue_buffered_image(vf); } -static int continue_buffered_image(struct vf_instance_s *vf) +extern const int under_mencoder; + +static int continue_buffered_image(struct vf_instance *vf) { int i=vf->priv->buffered_i; double pts = vf->priv->buffered_pts; @@ -362,10 +364,10 @@ static int continue_buffered_image(struct vf_instance_s *vf) dmpi->stride[2] = 2*mpi->stride[2]; } ret |= vf_next_put_image(vf, dmpi, pts); - if (correct_pts) + if (!under_mencoder) break; else - if (!i) vf_extra_flip(vf); + if (!i) vf_next_control(vf, VFCTRL_FLIP_PAGE, NULL); } break; case 1: @@ -392,10 +394,10 @@ static int continue_buffered_image(struct vf_instance_s *vf) mpi->chroma_width, mpi->chroma_height, (i^!tff)); } ret |= vf_next_put_image(vf, dmpi, pts); - if (correct_pts) + if (!under_mencoder) break; else - if (!i) vf_extra_flip(vf); + if (!i) vf_next_control(vf, VFCTRL_FLIP_PAGE, NULL); } break; case 2: @@ -418,10 +420,10 @@ static int continue_buffered_image(struct vf_instance_s *vf) dmpi->stride[2], mpi->stride[2]*2, (i^!tff)); } ret |= vf_next_put_image(vf, dmpi, pts); - if (correct_pts) + if (!under_mencoder) break; else - if (!i) vf_extra_flip(vf); + if (!i) vf_next_control(vf, VFCTRL_FLIP_PAGE, NULL); } break; } @@ -430,7 +432,7 @@ static int continue_buffered_image(struct vf_instance_s *vf) } #if 0 -static int query_format(struct vf_instance_s* vf, unsigned int fmt) +static int query_format(struct vf_instance* vf, unsigned int fmt) { /* FIXME - figure out which other formats work */ switch (fmt) { @@ -443,7 +445,7 @@ static int query_format(struct vf_instance_s* vf, unsigned int fmt) } #endif -static int config(struct vf_instance_s* vf, +static int config(struct vf_instance* vf, int width, int height, int d_width, int d_height, unsigned int flags, unsigned int outfmt) { @@ -459,7 +461,7 @@ static int config(struct vf_instance_s* vf, return 0; } -static void uninit(struct vf_instance_s* vf) +static void uninit(struct vf_instance* vf) { free(vf->priv); } diff --git a/libmpcodecs/vf_tile.c b/libmpcodecs/vf_tile.c index 8fc4b702fc..c5b4b90e96 100644 --- a/libmpcodecs/vf_tile.c +++ b/libmpcodecs/vf_tile.c @@ -68,7 +68,7 @@ struct vf_priv_s { }; -static int config(struct vf_instance_s* vf, +static int config(struct vf_instance* vf, int width, int height, int d_width, int d_height, unsigned int flags, unsigned int outfmt){ @@ -91,7 +91,7 @@ static int config(struct vf_instance_s* vf, } /* Filter handler */ -static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts) +static int put_image(struct vf_instance* vf, mp_image_t *mpi, double pts) { mp_image_t *dmpi; struct vf_priv_s *priv; @@ -176,14 +176,14 @@ static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts) } } -static void uninit(struct vf_instance_s* vf) +static void uninit(struct vf_instance* vf) { /* free local data */ free(vf->priv); } /* rgb/bgr 15->32 supported & some Yxxx */ -static int query_format(struct vf_instance_s* vf, unsigned int fmt) +static int query_format(struct vf_instance* vf, unsigned int fmt) { switch (fmt) { /* rgb 15 -> 32 bit */ diff --git a/libmpcodecs/vf_tinterlace.c b/libmpcodecs/vf_tinterlace.c index 3593091e5c..0658b2b322 100644 --- a/libmpcodecs/vf_tinterlace.c +++ b/libmpcodecs/vf_tinterlace.c @@ -37,7 +37,7 @@ struct vf_priv_s { mp_image_t *dmpi; }; -static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts) +static int put_image(struct vf_instance* vf, mp_image_t *mpi, double pts) { int ret = 0; mp_image_t *dmpi; @@ -176,7 +176,7 @@ static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts) return ret; } -static int query_format(struct vf_instance_s* vf, unsigned int fmt) +static int query_format(struct vf_instance* vf, unsigned int fmt) { /* FIXME - figure out which other formats work */ switch (fmt) { @@ -188,7 +188,7 @@ static int query_format(struct vf_instance_s* vf, unsigned int fmt) return 0; } -static int config(struct vf_instance_s* vf, +static int config(struct vf_instance* vf, int width, int height, int d_width, int d_height, unsigned int flags, unsigned int outfmt) { @@ -204,7 +204,7 @@ static int config(struct vf_instance_s* vf, return 0; } -static void uninit(struct vf_instance_s* vf) +static void uninit(struct vf_instance* vf) { free(vf->priv); } diff --git a/libmpcodecs/vf_unsharp.c b/libmpcodecs/vf_unsharp.c index d5deebfafb..9f2a7d4b98 100644 --- a/libmpcodecs/vf_unsharp.c +++ b/libmpcodecs/vf_unsharp.c @@ -126,7 +126,7 @@ static void unsharp( uint8_t *dst, uint8_t *src, int dstStride, int srcStride, i //===========================================================================// -static int config( struct vf_instance_s* vf, +static int config( struct vf_instance* vf, int width, int height, int d_width, int d_height, unsigned int flags, unsigned int outfmt ) { @@ -159,7 +159,7 @@ static int config( struct vf_instance_s* vf, //===========================================================================// -static void get_image( struct vf_instance_s* vf, mp_image_t *mpi ) { +static void get_image( struct vf_instance* vf, mp_image_t *mpi ) { if( mpi->flags & MP_IMGFLAG_PRESERVE ) return; // don't change if( mpi->imgfmt!=vf->priv->outfmt ) @@ -178,7 +178,7 @@ static void get_image( struct vf_instance_s* vf, mp_image_t *mpi ) { mpi->flags |= MP_IMGFLAG_DIRECT; } -static int put_image( struct vf_instance_s* vf, mp_image_t *mpi, double pts) { +static int put_image( struct vf_instance* vf, mp_image_t *mpi, double pts) { mp_image_t *dmpi; if( !(mpi->flags & MP_IMGFLAG_DIRECT) ) @@ -204,7 +204,7 @@ static int put_image( struct vf_instance_s* vf, mp_image_t *mpi, double pts) { return vf_next_put_image( vf, dmpi, pts); } -static void uninit( struct vf_instance_s* vf ) { +static void uninit( struct vf_instance* vf ) { unsigned int z; FilterParam *fp; @@ -227,7 +227,7 @@ static void uninit( struct vf_instance_s* vf ) { //===========================================================================// -static int query_format( struct vf_instance_s* vf, unsigned int fmt ) { +static int query_format( struct vf_instance* vf, unsigned int fmt ) { switch(fmt) { case IMGFMT_YV12: case IMGFMT_I420: @@ -263,7 +263,7 @@ static void parse( FilterParam *fp, char* args ) { //===========================================================================// -static unsigned int fmt_list[] = { +static const unsigned int fmt_list[] = { IMGFMT_YV12, IMGFMT_I420, IMGFMT_IYUV, diff --git a/libmpcodecs/vf_uspp.c b/libmpcodecs/vf_uspp.c index a5882ffeca..a0fca1503b 100644 --- a/libmpcodecs/vf_uspp.c +++ b/libmpcodecs/vf_uspp.c @@ -208,7 +208,7 @@ static void filter(struct vf_priv_s *p, uint8_t *dst[3], uint8_t *src[3], int ds } } -static int config(struct vf_instance_s* vf, +static int config(struct vf_instance* vf, int width, int height, int d_width, int d_height, unsigned int flags, unsigned int outfmt){ int i; @@ -249,7 +249,7 @@ static int config(struct vf_instance_s* vf, return vf_next_config(vf,width,height,d_width,d_height,flags,outfmt); } -static void get_image(struct vf_instance_s* vf, mp_image_t *mpi){ +static void get_image(struct vf_instance* vf, mp_image_t *mpi){ if(mpi->flags&MP_IMGFLAG_PRESERVE) return; // don't change // ok, we can do pp in-place (or pp disabled): vf->dmpi=vf_get_image(vf->next,mpi->imgfmt, @@ -266,7 +266,7 @@ static void get_image(struct vf_instance_s* vf, mp_image_t *mpi){ mpi->flags|=MP_IMGFLAG_DIRECT; } -static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){ +static int put_image(struct vf_instance* vf, mp_image_t *mpi, double pts){ mp_image_t *dmpi; if(!(mpi->flags&MP_IMGFLAG_DIRECT)){ @@ -301,7 +301,7 @@ static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){ return vf_next_put_image(vf,dmpi, pts); } -static void uninit(struct vf_instance_s* vf){ +static void uninit(struct vf_instance* vf){ int i; if(!vf->priv) return; @@ -320,7 +320,7 @@ static void uninit(struct vf_instance_s* vf){ } //===========================================================================// -static int query_format(struct vf_instance_s* vf, unsigned int fmt){ +static int query_format(struct vf_instance* vf, unsigned int fmt){ switch(fmt){ case IMGFMT_YV12: case IMGFMT_I420: @@ -332,7 +332,7 @@ static int query_format(struct vf_instance_s* vf, unsigned int fmt){ return 0; } -static int control(struct vf_instance_s* vf, int request, void* data){ +static int control(struct vf_instance* vf, int request, void* data){ switch(request){ case VFCTRL_QUERY_MAX_PP_LEVEL: return 8; diff --git a/libmpcodecs/vf_vo.c b/libmpcodecs/vf_vo.c index 4e0f1374c1..09425adcb0 100644 --- a/libmpcodecs/vf_vo.c +++ b/libmpcodecs/vf_vo.c @@ -1,6 +1,7 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <stdbool.h> #include "config.h" #include "mp_msg.h" @@ -23,7 +24,7 @@ extern float sub_delay; struct vf_priv_s { double pts; - const vo_functions_t *vo; + struct vo *vo; #ifdef CONFIG_ASS ass_renderer_t* ass_priv; int prev_visibility; @@ -31,9 +32,9 @@ struct vf_priv_s { }; #define video_out (vf->priv->vo) -static int query_format(struct vf_instance_s* vf, unsigned int fmt); /* forward declaration */ +static int query_format(struct vf_instance* vf, unsigned int fmt); /* forward declaration */ -static int config(struct vf_instance_s* vf, +static int config(struct vf_instance* vf, int width, int height, int d_width, int d_height, unsigned int flags, unsigned int outfmt){ @@ -43,8 +44,7 @@ static int config(struct vf_instance_s* vf, return 0; } - if(video_out->info) - { const vo_info_t *info = video_out->info; + const vo_info_t *info = video_out->driver->info; mp_msg(MSGT_CPLAYER,MSGL_INFO,"VO: [%s] %dx%d => %dx%d %s %s%s%s%s\n",info->short_name, width, height, d_width, d_height, @@ -57,12 +57,11 @@ static int config(struct vf_instance_s* vf, mp_msg(MSGT_CPLAYER,MSGL_V,"VO: Author: %s\n", info->author); if(info->comment && strlen(info->comment) > 0) mp_msg(MSGT_CPLAYER,MSGL_V,"VO: Comment: %s\n", info->comment); - } // save vo's stride capability for the wanted colorspace: vf->default_caps=query_format(vf,outfmt); - if(config_video_out(video_out,width,height,d_width,d_height,flags,"MPlayer",outfmt)) + if (vo_config(video_out, width, height, d_width, d_height, flags, "MPlayer", outfmt)) return 0; #ifdef CONFIG_ASS @@ -70,46 +69,47 @@ static int config(struct vf_instance_s* vf, ass_configure(vf->priv->ass_priv, width, height, !!(vf->default_caps & VFCAP_EOSD_UNSCALED)); #endif - ++vo_config_count; return 1; } -static int control(struct vf_instance_s* vf, int request, void* data) +static int control(struct vf_instance* vf, int request, void* data) { switch(request){ case VFCTRL_GET_DEINTERLACE: { if(!video_out) return CONTROL_FALSE; // vo not configured? - return(video_out->control(VOCTRL_GET_DEINTERLACE, data) - == VO_TRUE) ? CONTROL_TRUE : CONTROL_FALSE; + return vo_control(video_out, VOCTRL_GET_DEINTERLACE, data) == VO_TRUE; } case VFCTRL_SET_DEINTERLACE: { if(!video_out) return CONTROL_FALSE; // vo not configured? - return(video_out->control(VOCTRL_SET_DEINTERLACE, data) - == VO_TRUE) ? CONTROL_TRUE : CONTROL_FALSE; + return vo_control(video_out, VOCTRL_SET_DEINTERLACE, data) == VO_TRUE; } case VFCTRL_DRAW_OSD: - if(!vo_config_count) return CONTROL_FALSE; // vo not configured? - video_out->draw_osd(); + if(!video_out->config_ok) return CONTROL_FALSE; // vo not configured? + vo_draw_osd(video_out, data); return CONTROL_TRUE; + case VFCTRL_REDRAW_OSD: + return vo_control(video_out, VOCTRL_REDRAW_OSD, data) == true; case VFCTRL_FLIP_PAGE: { - if(!vo_config_count) return CONTROL_FALSE; // vo not configured? - video_out->flip_page(); + if(!video_out->config_ok) return CONTROL_FALSE; // vo not configured? + vo_flip_page(video_out); return CONTROL_TRUE; } case VFCTRL_SET_EQUALIZER: { vf_equalizer_t *eq=data; - if(!vo_config_count) return CONTROL_FALSE; // vo not configured? - return (video_out->control(VOCTRL_SET_EQUALIZER, eq->item, eq->value) == VO_TRUE) ? CONTROL_TRUE : CONTROL_FALSE; + if(!video_out->config_ok) return CONTROL_FALSE; // vo not configured? + struct voctrl_set_equalizer_args param = {eq->item, eq->value}; + return vo_control(video_out, VOCTRL_SET_EQUALIZER, ¶m) == VO_TRUE; } case VFCTRL_GET_EQUALIZER: { vf_equalizer_t *eq=data; - if(!vo_config_count) return CONTROL_FALSE; // vo not configured? - return (video_out->control(VOCTRL_GET_EQUALIZER, eq->item, &eq->value) == VO_TRUE) ? CONTROL_TRUE : CONTROL_FALSE; + if(!video_out->config_ok) return CONTROL_FALSE; // vo not configured? + struct voctrl_get_equalizer_args param = {eq->item, &eq->value}; + return vo_control(video_out, VOCTRL_GET_EQUALIZER, ¶m) == VO_TRUE; } #ifdef CONFIG_ASS case VFCTRL_INIT_EOSD: @@ -124,11 +124,11 @@ static int control(struct vf_instance_s* vf, int request, void* data) { mp_eosd_images_t images = {NULL, 2}; double pts = vf->priv->pts; - if (!vo_config_count || !vf->priv->ass_priv) return CONTROL_FALSE; + if (!video_out->config_ok || !vf->priv->ass_priv) return CONTROL_FALSE; if (sub_visibility && vf->priv->ass_priv && ass_track && (pts != MP_NOPTS_VALUE)) { mp_eosd_res_t res; memset(&res, 0, sizeof(res)); - if (video_out->control(VOCTRL_GET_EOSD_RES, &res) == VO_TRUE) { + if (vo_control(video_out, VOCTRL_GET_EOSD_RES, &res) == VO_TRUE) { ass_set_frame_size(vf->priv->ass_priv, res.w, res.h); ass_set_margins(vf->priv->ass_priv, res.mt, res.mb, res.ml, res.mr); ass_set_aspect_ratio(vf->priv->ass_priv, (double)res.w / res.h); @@ -141,7 +141,7 @@ static int control(struct vf_instance_s* vf, int request, void* data) } else vf->priv->prev_visibility = 0; vf->priv->prev_visibility = sub_visibility; - return (video_out->control(VOCTRL_DRAW_EOSD, &images) == VO_TRUE) ? CONTROL_TRUE : CONTROL_FALSE; + return vo_control(video_out, VOCTRL_DRAW_EOSD, &images) == VO_TRUE; } #endif case VFCTRL_GET_PTS: @@ -150,12 +150,11 @@ static int control(struct vf_instance_s* vf, int request, void* data) return CONTROL_TRUE; } } - // return video_out->control(request,data); return CONTROL_UNKNOWN; } -static int query_format(struct vf_instance_s* vf, unsigned int fmt){ - int flags=video_out->control(VOCTRL_QUERY_FORMAT,&fmt); +static int query_format(struct vf_instance* vf, unsigned int fmt){ + int flags = vo_control(video_out, VOCTRL_QUERY_FORMAT, &fmt); // draw_slice() accepts stride, draw_frame() doesn't: if(flags) if(fmt==IMGFMT_YV12 || fmt==IMGFMT_I420 || fmt==IMGFMT_IYUV) @@ -163,47 +162,48 @@ static int query_format(struct vf_instance_s* vf, unsigned int fmt){ return flags; } -static void get_image(struct vf_instance_s* vf, +static void get_image(struct vf_instance* vf, mp_image_t *mpi){ - if(!vo_config_count) return; + if (!video_out->config_ok) + return; // GET_IMAGE is required for hardware-accelerated formats if(vo_directrendering || IMGFMT_IS_XVMC(mpi->imgfmt) || IMGFMT_IS_VDPAU(mpi->imgfmt)) - video_out->control(VOCTRL_GET_IMAGE,mpi); + vo_control(video_out, VOCTRL_GET_IMAGE, mpi); } -static int put_image(struct vf_instance_s* vf, +static int put_image(struct vf_instance* vf, mp_image_t *mpi, double pts){ - if(!vo_config_count) return 0; // vo not configured? + if(!video_out->config_ok) return 0; // vo not configured? // record pts (potentially modified by filters) for main loop vf->priv->pts = pts; // first check, maybe the vo/vf plugin implements draw_image using mpi: - if(video_out->control(VOCTRL_DRAW_IMAGE,mpi)==VO_TRUE) return 1; // done. + if (vo_control(video_out, VOCTRL_DRAW_IMAGE,mpi)==VO_TRUE) return 1; // done. // nope, fallback to old draw_frame/draw_slice: if(!(mpi->flags&(MP_IMGFLAG_DIRECT|MP_IMGFLAG_DRAW_CALLBACK))){ // blit frame: // if(mpi->flags&MP_IMGFLAG_PLANAR) if(vf->default_caps&VFCAP_ACCEPT_STRIDE) - video_out->draw_slice(mpi->planes,mpi->stride,mpi->w,mpi->h,mpi->x,mpi->y); + vo_draw_slice(video_out, mpi->planes,mpi->stride,mpi->w,mpi->h,mpi->x,mpi->y); else - video_out->draw_frame(mpi->planes); + vo_draw_frame(video_out, mpi->planes); } return 1; } -static void start_slice(struct vf_instance_s* vf, +static void start_slice(struct vf_instance* vf, mp_image_t *mpi) { - if(!vo_config_count) return; // vo not configured? - video_out->control(VOCTRL_START_SLICE,mpi); + if(!video_out->config_ok) return; // vo not configured? + vo_control(video_out, VOCTRL_START_SLICE,mpi); } -static void draw_slice(struct vf_instance_s* vf, +static void draw_slice(struct vf_instance* vf, unsigned char** src, int* stride, int w,int h, int x, int y){ - if(!vo_config_count) return; // vo not configured? - video_out->draw_slice(src,stride,w,h,x,y); + if(!video_out->config_ok) return; // vo not configured? + vo_draw_slice(video_out, src,stride,w,h,x,y); } -static void uninit(struct vf_instance_s* vf) +static void uninit(struct vf_instance* vf) { if (vf->priv) { #ifdef CONFIG_ASS @@ -225,9 +225,8 @@ static int open(vf_instance_t *vf, char* args){ vf->start_slice=start_slice; vf->uninit=uninit; vf->priv=calloc(1, sizeof(struct vf_priv_s)); - vf->priv->vo = (const vo_functions_t *)args; + vf->priv->vo = (struct vo *)args; if(!video_out) return 0; // no vo ? -// if(video_out->preinit(args)) return 0; // preinit failed return 1; } diff --git a/libmpcodecs/vf_yadif.c b/libmpcodecs/vf_yadif.c index 5a36b3caea..6f324dc4fa 100644 --- a/libmpcodecs/vf_yadif.c +++ b/libmpcodecs/vf_yadif.c @@ -26,6 +26,7 @@ #include "config.h" #include "cpudetect.h" +#include "options.h" #include "mp_msg.h" @@ -368,7 +369,7 @@ static void filter(struct vf_priv_s *p, uint8_t *dst[3], int dst_stride[3], int #endif } -static int config(struct vf_instance_s* vf, +static int config(struct vf_instance* vf, int width, int height, int d_width, int d_height, unsigned int flags, unsigned int outfmt){ int i, j; @@ -386,10 +387,9 @@ static int config(struct vf_instance_s* vf, return vf_next_config(vf,width,height,d_width,d_height,flags,outfmt); } -static int continue_buffered_image(struct vf_instance_s *vf); -extern int correct_pts; +static int continue_buffered_image(struct vf_instance *vf); -static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){ +static int put_image(struct vf_instance* vf, mp_image_t *mpi, double pts){ int tff; if(vf->priv->parity < 0) { @@ -416,7 +416,9 @@ static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){ return continue_buffered_image(vf); } -static int continue_buffered_image(struct vf_instance_s *vf) +extern const int under_mencoder; + +static int continue_buffered_image(struct vf_instance *vf) { mp_image_t *mpi = vf->priv->buffered_mpi; int tff = vf->priv->buffered_tff; @@ -434,19 +436,19 @@ static int continue_buffered_image(struct vf_instance_s *vf) mpi->width,mpi->height); vf_clone_mpi_attributes(dmpi, mpi); filter(vf->priv, dmpi->planes, dmpi->stride, mpi->w, mpi->h, i ^ tff ^ 1, tff); - if (correct_pts && i < (vf->priv->mode & 1)) + if (i < (vf->priv->mode & 1) && !under_mencoder) vf_queue_frame(vf, continue_buffered_image); ret |= vf_next_put_image(vf, dmpi, pts /*FIXME*/); - if (correct_pts) + if (!under_mencoder) break; if(i<(vf->priv->mode&1)) - vf_extra_flip(vf); + vf_next_control(vf, VFCTRL_FLIP_PAGE, NULL); } vf->priv->buffered_i = 1; return ret; } -static void uninit(struct vf_instance_s* vf){ +static void uninit(struct vf_instance* vf){ int i; if(!vf->priv) return; @@ -460,7 +462,7 @@ static void uninit(struct vf_instance_s* vf){ } //===========================================================================// -static int query_format(struct vf_instance_s* vf, unsigned int fmt){ +static int query_format(struct vf_instance* vf, unsigned int fmt){ switch(fmt){ case IMGFMT_YV12: case IMGFMT_I420: @@ -472,7 +474,7 @@ static int query_format(struct vf_instance_s* vf, unsigned int fmt){ return 0; } -static int control(struct vf_instance_s* vf, int request, void* data){ +static int control(struct vf_instance* vf, int request, void* data){ switch (request){ case VFCTRL_GET_DEINTERLACE: *(int*)data = vf->priv->do_deinterlace; diff --git a/libmpcodecs/vf_yuvcsp.c b/libmpcodecs/vf_yuvcsp.c index 1cb6a187f5..891bc095df 100644 --- a/libmpcodecs/vf_yuvcsp.c +++ b/libmpcodecs/vf_yuvcsp.c @@ -16,7 +16,7 @@ struct vf_priv_s { //===========================================================================// -static int config(struct vf_instance_s* vf, +static int config(struct vf_instance* vf, int width, int height, int d_width, int d_height, unsigned int flags, unsigned int outfmt){ return vf_next_config(vf, width, height, d_width, d_height, flags, outfmt); @@ -30,7 +30,7 @@ static inline int clamp_c(int x){ return (x > 240) ? 240 : (x < 16) ? 16 : x; } -static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){ +static int put_image(struct vf_instance* vf, mp_image_t *mpi, double pts){ int i,j; uint8_t *y_in, *cb_in, *cr_in; uint8_t *y_out, *cb_out, *cr_out; @@ -64,12 +64,12 @@ static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){ //===========================================================================// /* -static void uninit(struct vf_instance_s* vf){ +static void uninit(struct vf_instance* vf){ free(vf->priv); } */ -static int query_format(struct vf_instance_s* vf, unsigned int fmt){ +static int query_format(struct vf_instance* vf, unsigned int fmt){ switch(fmt){ case IMGFMT_YV12: case IMGFMT_I420: diff --git a/libmpcodecs/vf_yuy2.c b/libmpcodecs/vf_yuy2.c index f8b9e5372c..58752db6aa 100644 --- a/libmpcodecs/vf_yuy2.c +++ b/libmpcodecs/vf_yuy2.c @@ -16,7 +16,7 @@ //===========================================================================// -static int config(struct vf_instance_s* vf, +static int config(struct vf_instance* vf, int width, int height, int d_width, int d_height, unsigned int flags, unsigned int outfmt){ @@ -30,7 +30,7 @@ static int config(struct vf_instance_s* vf, return vf_next_config(vf,width,height,d_width,d_height,flags,IMGFMT_YUY2); } -static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){ +static int put_image(struct vf_instance* vf, mp_image_t *mpi, double pts){ mp_image_t *dmpi; // hope we'll get DR buffer: @@ -52,7 +52,7 @@ static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){ //===========================================================================// -static int query_format(struct vf_instance_s* vf, unsigned int fmt){ +static int query_format(struct vf_instance* vf, unsigned int fmt){ switch(fmt){ case IMGFMT_YV12: case IMGFMT_I420: diff --git a/libmpcodecs/vf_yvu9.c b/libmpcodecs/vf_yvu9.c index e82ab48f61..d0c2aab3a3 100644 --- a/libmpcodecs/vf_yvu9.c +++ b/libmpcodecs/vf_yvu9.c @@ -15,7 +15,7 @@ //===========================================================================// -static int config(struct vf_instance_s* vf, +static int config(struct vf_instance* vf, int width, int height, int d_width, int d_height, unsigned int flags, unsigned int outfmt){ @@ -27,7 +27,7 @@ static int config(struct vf_instance_s* vf, return vf_next_config(vf,width,height,d_width,d_height,flags,IMGFMT_YV12); } -static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){ +static int put_image(struct vf_instance* vf, mp_image_t *mpi, double pts){ mp_image_t *dmpi; int y,w,h; @@ -62,7 +62,7 @@ static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){ //===========================================================================// -static int query_format(struct vf_instance_s* vf, unsigned int fmt){ +static int query_format(struct vf_instance* vf, unsigned int fmt){ if (fmt == IMGFMT_YVU9 || fmt == IMGFMT_IF09) return vf_next_query_format(vf,IMGFMT_YV12) & (~VFCAP_CSP_SUPPORTED_BY_HW); return 0; diff --git a/libmpcodecs/vf_zrmjpeg.c b/libmpcodecs/vf_zrmjpeg.c index 0d45666aa4..32b4f9b7bc 100644 --- a/libmpcodecs/vf_zrmjpeg.c +++ b/libmpcodecs/vf_zrmjpeg.c @@ -666,7 +666,7 @@ struct vf_priv_s { * arrange to dispatch to the config() entry pointer for the one * selected. */ -static int config(struct vf_instance_s* vf, int width, int height, int d_width, +static int config(struct vf_instance* vf, int width, int height, int d_width, int d_height, unsigned int flags, unsigned int outfmt){ struct vf_priv_s *priv = vf->priv; float aspect_decision; @@ -826,7 +826,7 @@ static int config(struct vf_instance_s* vf, int width, int height, int d_width, * \param mpi pointer to mp_image_t structure * \param pts */ -static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){ +static int put_image(struct vf_instance* vf, mp_image_t *mpi, double pts){ struct vf_priv_s *priv = vf->priv; int size = 0; int i; @@ -855,7 +855,7 @@ static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){ * Given the image format specified by \a fmt, this routine is called * to ask if the format is supported or not. */ -static int query_format(struct vf_instance_s* vf, unsigned int fmt){ +static int query_format(struct vf_instance* vf, unsigned int fmt){ VERBOSE("query_format() called\n"); switch (fmt) { diff --git a/libmpdemux/aviheader.c b/libmpdemux/aviheader.c index 85a84e8ca3..fa7f27c4fc 100644 --- a/libmpdemux/aviheader.c +++ b/libmpdemux/aviheader.c @@ -42,7 +42,7 @@ static int odml_get_vstream_id(int id, unsigned char res[]) return 0; } -int avi_idx_cmp(const void *elem1,const void *elem2) { +static int avi_idx_cmp(const void *elem1,const void *elem2) { register off_t a = AVI_IDX_OFFSET((AVIINDEXENTRY *)elem1); register off_t b = AVI_IDX_OFFSET((AVIINDEXENTRY *)elem2); return (a > b) - (b > a); diff --git a/libmpdemux/demux_avi.c b/libmpdemux/demux_avi.c index fa1fc91e48..9695fcb556 100644 --- a/libmpdemux/demux_avi.c +++ b/libmpdemux/demux_avi.c @@ -24,7 +24,9 @@ extern const demuxer_desc_t demuxer_desc_avi_nini; int pts_from_bps=1; // Select ds from ID -demux_stream_t* demux_avi_select_stream(demuxer_t *demux,unsigned int id){ +static demux_stream_t* demux_avi_select_stream(demuxer_t *demux, + unsigned int id) +{ int stream_id=avi_stream_id(id); @@ -277,7 +279,7 @@ do{ // return value: // 0 = EOF or no stream found // 1 = successfully read a packet -int demux_avi_fill_buffer_ni(demuxer_t *demux,demux_stream_t* ds){ +static int demux_avi_fill_buffer_ni(demuxer_t *demux,demux_stream_t* ds){ avi_priv_t *priv=demux->priv; unsigned int id=0; unsigned int len; @@ -341,7 +343,7 @@ do{ // return value: // 0 = EOF or no stream found // 1 = successfully read a packet -int demux_avi_fill_buffer_nini(demuxer_t *demux,demux_stream_t* ds){ +static int demux_avi_fill_buffer_nini(demuxer_t *demux,demux_stream_t* ds){ avi_priv_t *priv=demux->priv; unsigned int id=0; unsigned int len; @@ -572,7 +574,7 @@ static demuxer_t* demux_open_avi(demuxer_t* demuxer){ } -void demux_seek_avi(demuxer_t *demuxer,float rel_seek_secs,float audio_delay,int flags){ +static void demux_seek_avi(demuxer_t *demuxer,float rel_seek_secs,float audio_delay,int flags){ avi_priv_t *priv=demuxer->priv; demux_stream_t *d_audio=demuxer->audio; demux_stream_t *d_video=demuxer->video; @@ -745,7 +747,7 @@ void demux_seek_avi(demuxer_t *demuxer,float rel_seek_secs,float audio_delay,int } -void demux_close_avi(demuxer_t *demuxer) { +static void demux_close_avi(demuxer_t *demuxer) { avi_priv_t* priv=demuxer->priv; if(!priv) @@ -837,6 +839,7 @@ static int avi_check_file(demuxer_t *demuxer) static demuxer_t* demux_open_hack_avi(demuxer_t *demuxer) { + struct MPOpts *opts = demuxer->opts; sh_audio_t* sh_a; demuxer = demux_open_avi(demuxer); @@ -851,7 +854,7 @@ static demuxer_t* demux_open_hack_avi(demuxer_t *demuxer) stream_t* s; demuxer_t *od; s = new_ds_stream(demuxer->audio); - od = new_demuxer(s,DEMUXER_TYPE_OGG,-1,-2,-2,NULL); + od = new_demuxer(opts, s,DEMUXER_TYPE_OGG,-1,-2,-2,NULL); if(!demux_ogg_open(od)) { mp_msg( MSGT_DEMUXER,MSGL_ERR,MSGTR_ErrorOpeningOGGDemuxer); free_stream(s); diff --git a/libmpdemux/demux_avs.c b/libmpdemux/demux_avs.c index 8d2ac82046..444e06c90c 100644 --- a/libmpdemux/demux_avs.c +++ b/libmpdemux/demux_avs.c @@ -85,7 +85,7 @@ typedef struct tagAVS imp_avs_get_audio avs_get_audio; } AVS_T; -AVS_T *initAVS(const char *filename) +static AVS_T *initAVS(const char *filename) { AVS_T *AVS = malloc (sizeof(AVS_T)); AVS_Value arg0 = avs_new_value_string(filename); diff --git a/libmpdemux/demux_lavf.c b/libmpdemux/demux_lavf.c index 9749054a03..047315e74c 100644 --- a/libmpdemux/demux_lavf.c +++ b/libmpdemux/demux_lavf.c @@ -24,6 +24,7 @@ #include <limits.h> #include "config.h" +#include "options.h" #include "mp_msg.h" #include "help_mp.h" #include "av_opts.h" @@ -43,9 +44,6 @@ #define PROBE_BUF_SIZE 2048 -extern char *audio_lang; -extern char *dvdsub_lang; -extern int dvdsub_id; static unsigned int opt_probesize = 0; static unsigned int opt_analyzeduration = 0; static char *opt_format; @@ -418,6 +416,7 @@ static void handle_stream(demuxer_t *demuxer, AVFormatContext *avfc, int i) { } static demuxer_t* demux_open_lavf(demuxer_t *demuxer){ + struct MPOpts *opts = demuxer->opts; AVFormatContext *avfc; AVFormatParameters ap; const AVOption *opt; @@ -433,7 +432,7 @@ static demuxer_t* demux_open_lavf(demuxer_t *demuxer){ if (opt_cryptokey) parse_cryptokey(avfc, opt_cryptokey); - if (user_correct_pts != 0) + if (opts->user_correct_pts != 0) avfc->flags |= AVFMT_FLAG_GENPTS; if (index_mode == 0) avfc->flags |= AVFMT_FLAG_IGNIDX; diff --git a/libmpdemux/demux_mkv.c b/libmpdemux/demux_mkv.c index 6d4429377c..76a3874723 100644 --- a/libmpdemux/demux_mkv.c +++ b/libmpdemux/demux_mkv.c @@ -13,6 +13,7 @@ #include <ctype.h> #include <inttypes.h> +#include "options.h" #include "stream/stream.h" #include "demuxer.h" #include "stheader.h" @@ -55,13 +56,12 @@ static const unsigned char sipr_swaps[38][2]={ #define ATRC_FLAVORS 8 #define COOK_FLAVORS 34 static const int sipr_fl2bps[SIPR_FLAVORS] = {813, 1062, 625, 2000}; -static const int atrc_fl2bps[ATRC_FLAVORS] = - {8269, 11714, 13092, 16538, 18260, 22050, 33075, 44100}; -static const int cook_fl2bps[COOK_FLAVORS] = - { 1000, 1378, 2024, 2584, 4005, 5513, 8010, 4005, 750, 2498, - 4048, 5513, 8010, 11973, 8010, 2584, 4005, 2067, 2584, 2584, - 4005, 4005, 5513, 5513, 8010, 12059, 1550, 8010, 12059, 5513, - 12016, 16408, 22911, 33506}; +static const int atrc_fl2bps[ATRC_FLAVORS] = {8269, 11714, 13092, 16538, 18260, 22050, 33075, 44100}; +static const int cook_fl2bps[COOK_FLAVORS] = { + 1000, 1378, 2024, 2584, 4005, 5513, 8010, 4005, 750, 2498, + 4048, 5513, 8010, 11973, 8010, 2584, 4005, 2067, 2584, 2584, + 4005, 4005, 5513, 5513, 8010, 12059, 1550, 8010, 12059, 5513, + 12016, 16408, 22911, 33506}; typedef struct { @@ -93,7 +93,7 @@ typedef struct mkv_track int default_track; - void *private_data; + unsigned char *private_data; unsigned int private_size; /* stuff for realmedia */ @@ -182,20 +182,16 @@ typedef struct mkv_demuxer #define RAPROPERTIES4_SIZE 56 #define RAPROPERTIES5_SIZE 70 -/* for e.g. "-slang ger" */ -extern char *dvdsub_lang; -extern char *audio_lang; -extern int dvdsub_id; - /** * \brief ensures there is space for at least one additional element * \param array array to grow * \param nelem current number of elements in array * \param elsize size of one array element */ -static void grow_array(void **array, int nelem, size_t elsize) { +static void *grow_array(void *array, int nelem, size_t elsize) { if (!(nelem & 31)) - *array = realloc(*array, (nelem + 32) * elsize); + array = realloc(array, (nelem + 32) * elsize); + return array; } static mkv_track_t * @@ -220,8 +216,9 @@ add_cluster_position (mkv_demuxer_t *mkv_d, uint64_t position) if (mkv_d->cluster_positions[i] == position) return; - grow_array(&mkv_d->cluster_positions, mkv_d->num_cluster_pos, - sizeof(uint64_t)); + mkv_d->cluster_positions = grow_array(mkv_d->cluster_positions, + mkv_d->num_cluster_pos, + sizeof(uint64_t)); mkv_d->cluster_positions[mkv_d->num_cluster_pos++] = position; } @@ -1064,7 +1061,8 @@ demux_mkv_read_cues (demuxer_t *demuxer) if (time != EBML_UINT_INVALID && track != EBML_UINT_INVALID && pos != EBML_UINT_INVALID) { - grow_array(&mkv_d->indexes, mkv_d->num_indexes, sizeof(mkv_index_t)); + mkv_d->indexes = grow_array(mkv_d->indexes, mkv_d->num_indexes, + sizeof(mkv_index_t)); mkv_d->indexes[mkv_d->num_indexes].tnum = track; mkv_d->indexes[mkv_d->num_indexes].timecode = time; mkv_d->indexes[mkv_d->num_indexes].filepos =mkv_d->segment_start+pos; @@ -1514,6 +1512,7 @@ static const videocodec_info_t vinfo[] = { static int demux_mkv_open_video (demuxer_t *demuxer, mkv_track_t *track, int vid) { + struct MPOpts *opts = demuxer->opts; BITMAPINFOHEADER *bih; void *ImageDesc = NULL; sh_video_t *sh_v; @@ -1624,7 +1623,7 @@ demux_mkv_open_video (demuxer_t *demuxer, mkv_track_t *track, int vid) bih = realloc (bih, bih->biSize); memcpy (bih + 1, track->private_data, track->private_size); } - track->reorder_timecodes = user_correct_pts == 0; + track->reorder_timecodes = opts->user_correct_pts == 0; if (!vi->id) { mp_msg (MSGT_DEMUX,MSGL_WARN, MSGTR_MPDEMUX_MKV_UnknownCodecID, track->codec_id, track->tnum); @@ -1950,13 +1949,13 @@ demux_mkv_open_audio (demuxer_t *demuxer, mkv_track_t *track, int aid) if (track->a_formattag == mmioFOURCC('f', 'L', 'a', 'C')) { - ptr = (unsigned char *)track->private_data; + ptr = track->private_data; size = track->private_size; } else { sh_a->format = mmioFOURCC('f', 'L', 'a', 'C'); - ptr = (unsigned char *) track->private_data + ptr = track->private_data + sizeof (WAVEFORMATEX); size = track->private_size - sizeof (WAVEFORMATEX); } @@ -2026,8 +2025,6 @@ demux_mkv_open_sub (demuxer_t *demuxer, mkv_track_t *track, int sid) return 0; } -static void demux_mkv_seek (demuxer_t *demuxer, float rel_seek_secs, float audio_delay, int flags); - static int demux_mkv_open (demuxer_t *demuxer) { diff --git a/libmpdemux/demux_mov.c b/libmpdemux/demux_mov.c index 8217c47a95..fb271e1e49 100644 --- a/libmpdemux/demux_mov.c +++ b/libmpdemux/demux_mov.c @@ -144,7 +144,7 @@ typedef struct { void* desc; // image/sound/etc description (pointer to ImageDescription etc) } mov_track_t; -void mov_build_index(mov_track_t* trak,int timescale){ +static void mov_build_index(mov_track_t* trak,int timescale){ int i,j,s; int last=trak->chunks_size; unsigned int pts=0; @@ -1917,6 +1917,7 @@ static int lschunks_intrak(demuxer_t* demuxer, int level, unsigned int id, } static demuxer_t* mov_read_header(demuxer_t* demuxer){ + struct MPOpts *opts = demuxer->opts; mov_priv_t* priv=demuxer->priv; int t_no; int best_a_id=-1, best_a_len=0; @@ -1992,7 +1993,7 @@ static demuxer_t* mov_read_header(demuxer_t* demuxer){ demuxer->video->id = t_no; s = new_ds_stream(demuxer->video); - od = demux_open(s, DEMUXER_TYPE_MPEG_PS, -1, -1, -1, NULL); + od = demux_open(opts, s, DEMUXER_TYPE_MPEG_PS, -1, -1, -1, NULL); if(od) return new_demuxers_demuxer(od, od, od); demuxer->video->id = -2; //new linked demuxer couldn't be allocated break; diff --git a/libmpdemux/demux_mpg.c b/libmpdemux/demux_mpg.c index 8edb6e7a1e..489821f878 100644 --- a/libmpdemux/demux_mpg.c +++ b/libmpdemux/demux_mpg.c @@ -794,7 +794,7 @@ static int demux_mpg_gxf_fill_buffer(demuxer_t *demux, demux_stream_t *ds) { return 1; } -int demux_mpg_fill_buffer(demuxer_t *demux, demux_stream_t *ds){ +static int demux_mpg_fill_buffer(demuxer_t *demux, demux_stream_t *ds){ unsigned int head=0; int skipped=0; int max_packs=256; // 512kbyte @@ -881,7 +881,7 @@ do{ void skip_audio_frame(sh_audio_t *sh_audio); -void demux_seek_mpg(demuxer_t *demuxer,float rel_seek_secs,float audio_delay, int flags){ +static void demux_seek_mpg(demuxer_t *demuxer,float rel_seek_secs,float audio_delay, int flags){ demux_stream_t *d_audio=demuxer->audio; demux_stream_t *d_video=demuxer->video; sh_audio_t *sh_audio=d_audio->sh; @@ -987,7 +987,7 @@ void demux_seek_mpg(demuxer_t *demuxer,float rel_seek_secs,float audio_delay, in } } -int demux_mpg_control(demuxer_t *demuxer,int cmd, void *arg){ +static int demux_mpg_control(demuxer_t *demuxer,int cmd, void *arg){ mpg_demuxer_t *mpg_d=(mpg_demuxer_t*)demuxer->priv; switch(cmd) { diff --git a/libmpdemux/demux_nemesi.c b/libmpdemux/demux_nemesi.c index c1ed7f1089..704f14cf81 100644 --- a/libmpdemux/demux_nemesi.c +++ b/libmpdemux/demux_nemesi.c @@ -455,7 +455,7 @@ static void demux_seek_rtp(demuxer_t *demuxer, float rel_seek_secs, mp_msg(MSGT_DEMUX, MSGL_ERR, "Unsupported seek type\n"); } -static int demux_rtp_control(struct demuxer_st *demuxer, int cmd, void *arg) +static int demux_rtp_control(struct demuxer *demuxer, int cmd, void *arg) { Nemesi_DemuxerStreamData * ndsd = demuxer->priv; rtsp_ctrl * ctl = ndsd->rtsp; diff --git a/libmpdemux/demux_ogg.c b/libmpdemux/demux_ogg.c index 2561714517..013bff5a76 100644 --- a/libmpdemux/demux_ogg.c +++ b/libmpdemux/demux_ogg.c @@ -8,6 +8,7 @@ #include <math.h> #include <inttypes.h> +#include "options.h" #include "mp_msg.h" #include "help_mp.h" #include "stream/stream.h" @@ -146,7 +147,6 @@ typedef struct ogg_demuxer { #define PACKET_IS_SYNCPOINT 0x08 extern char *dvdsub_lang, *audio_lang; -extern int dvdsub_id; //-------- subtitle support - should be moved to decoder layer, and queue // - subtitles up in demuxer buffer... @@ -158,7 +158,7 @@ extern int dvdsub_id; static subtitle ogg_sub; //FILE* subout; -void demux_ogg_add_sub (ogg_stream_t* os,ogg_packet* pack) { +static void demux_ogg_add_sub (ogg_stream_t* os,ogg_packet* pack) { int lcv; char *packet = pack->packet; @@ -395,7 +395,7 @@ static void demux_ogg_check_comments(demuxer_t *d, ogg_stream_t *os, int id, vor if (os->text && d->sub->id < 0 && demux_ogg_check_lang(val, dvdsub_lang)) { d->sub->id = index; - dvdsub_id = index; + d->opts->sub_id = index; mp_msg(MSGT_DEMUX, MSGL_V, "Ogg demuxer: Displaying subtitle stream id %d which matched -slang %s\n", id, val); } else @@ -491,7 +491,7 @@ static int demux_ogg_add_packet(demux_stream_t* ds,ogg_stream_t* os,int id,ogg_p /// if -forceidx build a table of all syncpoints to make seeking easier /// otherwise try to get at least the final_granulepos -void demux_ogg_scan_stream(demuxer_t* demuxer) { +static void demux_ogg_scan_stream(demuxer_t* demuxer) { ogg_demuxer_t* ogg_d = demuxer->priv; stream_t *s = demuxer->stream; ogg_sync_state* sync = &ogg_d->sync; @@ -1216,6 +1216,7 @@ static int demux_ogg_fill_buffer(demuxer_t *d, demux_stream_t *dsds) { /// For avi with Ogg audio stream we have to create an ogg demuxer for this // stream, then we join the avi and ogg demuxer with a demuxers demuxer demuxer_t* init_avi_with_ogg(demuxer_t* demuxer) { + struct MPOpts *opts = demuxer->opts; demuxer_t *od; ogg_demuxer_t *ogg_d; stream_t* s; @@ -1277,7 +1278,7 @@ demuxer_t* init_avi_with_ogg(demuxer_t* demuxer) { // Create the ds_stream and the ogg demuxer s = new_ds_stream(demuxer->audio); - od = new_demuxer(s,DEMUXER_TYPE_OGG,0,-2,-2,NULL); + od = new_demuxer(opts, s,DEMUXER_TYPE_OGG,0,-2,-2,NULL); /// Add the header packets in the ogg demuxer audio stream for (i = 0; i < 3; i++) { diff --git a/libmpdemux/demux_pva.c b/libmpdemux/demux_pva.c index 2ff8be63e3..af16f1c3da 100644 --- a/libmpdemux/demux_pva.c +++ b/libmpdemux/demux_pva.c @@ -62,7 +62,7 @@ typedef struct { -int pva_sync(demuxer_t * demuxer) +static int pva_sync(demuxer_t * demuxer) { uint8_t buffer[5]={0,0,0,0,0}; int count; diff --git a/libmpdemux/demux_rtp.cpp b/libmpdemux/demux_rtp.cpp index aaa525fc4c..fd6dffa0e3 100644 --- a/libmpdemux/demux_rtp.cpp +++ b/libmpdemux/demux_rtp.cpp @@ -8,6 +8,7 @@ extern "C" { #endif #include "demux_rtp.h" #include "stheader.h" +#include "options.h" } #include "demux_rtp_internal.h" @@ -95,8 +96,8 @@ static char* openURL_sip(SIPClient* client, char const* url) { int rtspStreamOverTCP = 0; extern int rtsp_port; -extern "C" int audio_id, video_id, dvdsub_id; extern "C" demuxer_t* demux_open_rtp(demuxer_t* demuxer) { + struct MPOpts *opts = demuxer->opts; Boolean success = False; do { TaskScheduler* scheduler = BasicTaskScheduler::createNew(); @@ -256,8 +257,9 @@ extern "C" demuxer_t* demux_open_rtp(demuxer_t* demuxer) { // code to recognize this: if (demux_is_multiplexed_rtp_stream(demuxer)) { stream_t* s = new_ds_stream(demuxer->video); - demuxer_t* od = demux_open(s, DEMUXER_TYPE_UNKNOWN, - audio_id, video_id, dvdsub_id, NULL); + demuxer_t* od = demux_open(opts, s, DEMUXER_TYPE_UNKNOWN, + opts->audio_id, opts->video_id, opts->sub_id, + NULL); demuxer = new_demuxers_demuxer(od, od, od); } @@ -637,7 +639,7 @@ demux_packet_t* ReadBufferQueue::getPendingBuffer() { return dp; } -static int demux_rtp_control(struct demuxer_st *demuxer, int cmd, void *arg) { +static int demux_rtp_control(struct demuxer *demuxer, int cmd, void *arg) { double endpts = ((RTPState*)demuxer->priv)->mediaSession->playEndTime(); switch(cmd) { diff --git a/libmpdemux/demuxer.c b/libmpdemux/demuxer.c index 74bbd8e559..6c3792b1d9 100644 --- a/libmpdemux/demuxer.c +++ b/libmpdemux/demuxer.c @@ -9,6 +9,7 @@ #include <sys/stat.h> #include "config.h" +#include "options.h" #include "mp_msg.h" #include "help_mp.h" #include "m_config.h" @@ -168,7 +169,7 @@ void free_demuxer_stream(demux_stream_t *ds) free(ds); } -demux_stream_t *new_demuxer_stream(struct demuxer_st *demuxer, int id) +demux_stream_t *new_demuxer_stream(struct demuxer *demuxer, int id) { demux_stream_t *ds = malloc(sizeof(demux_stream_t)); ds->buffer_pos = ds->buffer_size = 0; @@ -214,8 +215,8 @@ static const demuxer_desc_t *get_demuxer_desc_from_type(int file_format) } -demuxer_t *new_demuxer(stream_t *stream, int type, int a_id, int v_id, - int s_id, char *filename) +demuxer_t *new_demuxer(struct MPOpts *opts, stream_t *stream, int type, + int a_id, int v_id, int s_id, char *filename) { demuxer_t *d = malloc(sizeof(demuxer_t)); memset(d, 0, sizeof(demuxer_t)); @@ -231,6 +232,7 @@ demuxer_t *new_demuxer(stream_t *stream, int type, int a_id, int v_id, d->video = new_demuxer_stream(d, v_id); d->sub = new_demuxer_stream(d, s_id); d->type = type; + d->opts = opts; if (type) if (!(d->desc = get_demuxer_desc_from_type(type))) mp_msg(MSGT_DEMUXER, MSGL_ERR, @@ -243,8 +245,6 @@ demuxer_t *new_demuxer(stream_t *stream, int type, int a_id, int v_id, return d; } -extern int dvdsub_id; - sh_sub_t *new_sh_sub_sid(demuxer_t *demuxer, int id, int sid) { if (id > MAX_S_STREAMS - 1 || id < 0) { @@ -259,12 +259,13 @@ sh_sub_t *new_sh_sub_sid(demuxer_t *demuxer, int id, int sid) sh_sub_t *sh = calloc(1, sizeof(sh_sub_t)); demuxer->s_streams[id] = sh; sh->sid = sid; + sh->opts = demuxer->opts; mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_SUBTITLE_ID=%d\n", sid); } return demuxer->s_streams[id]; } -void free_sh_sub(sh_sub_t *sh) +static void free_sh_sub(sh_sub_t *sh) { mp_msg(MSGT_DEMUXER, MSGL_DBG2, "DEMUXER: freeing sh_sub at %p\n", sh); free(sh->extradata); @@ -284,11 +285,11 @@ sh_audio_t *new_sh_audio_aid(demuxer_t *demuxer, int id, int aid) MAX_A_STREAMS); return NULL; } - if (demuxer->a_streams[id]) + if (demuxer->a_streams[id]) { mp_msg(MSGT_DEMUXER, MSGL_WARN, MSGTR_AudioStreamRedefined, id); - else { - sh_audio_t *sh = calloc(1, sizeof(sh_audio_t)); + } else { mp_msg(MSGT_DEMUXER, MSGL_V, MSGTR_FoundAudioStream, id); + sh_audio_t *sh = calloc(1, sizeof(sh_audio_t)); demuxer->a_streams[id] = sh; sh->aid = aid; sh->ds = demuxer->audio; @@ -297,6 +298,7 @@ sh_audio_t *new_sh_audio_aid(demuxer_t *demuxer, int id, int aid) sh->sample_format = AF_FORMAT_S16_NE; sh->audio_out_minsize = 8192; /* default size, maybe not enough for Win32/ACM */ sh->pts = MP_NOPTS_VALUE; + sh->opts = demuxer->opts; mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_AUDIO_ID=%d\n", aid); } return demuxer->a_streams[id]; @@ -324,11 +326,12 @@ sh_video_t *new_sh_video_vid(demuxer_t *demuxer, int id, int vid) if (demuxer->v_streams[id]) mp_msg(MSGT_DEMUXER, MSGL_WARN, MSGTR_VideoStreamRedefined, id); else { - sh_video_t *sh = calloc(1, sizeof(sh_video_t)); mp_msg(MSGT_DEMUXER, MSGL_V, MSGTR_FoundVideoStream, id); + sh_video_t *sh = calloc(1, sizeof *sh); demuxer->v_streams[id] = sh; sh->vid = vid; sh->ds = demuxer->video; + sh->opts = demuxer->opts; mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_VIDEO_ID=%d\n", vid); } return demuxer->v_streams[id]; @@ -490,6 +493,14 @@ int ds_fill_buffer(demux_stream_t *ds) if (!ds->first) ds->last = NULL; --ds->packs; + /* The code below can set ds->eof to 1 when another stream runs + * out of buffer space. That makes sense because in that situation + * the calling code should not count on being able to demux more + * packets from this stream. + * If however the situation improves and we're called again + * despite the eof flag then it's better to clear it to avoid + * weird behavior. */ + ds->eof = 0; return 1; } if (demux->audio->packs >= MAX_PACKS @@ -745,9 +756,6 @@ int get_demuxer_type_from_name(char *demuxer_name, int *force) int extension_parsing = 1; // 0=off 1=mixed (used only for unstable formats) -int correct_pts = 0; -int user_correct_pts = -1; - /* NOTE : Several demuxers may be opened at the same time so demuxers should NEVER rely on an external var to enable them @@ -761,9 +769,10 @@ int user_correct_pts = -1; (ex: tv,mf). */ -static demuxer_t *demux_open_stream(stream_t *stream, int file_format, - int force, int audio_id, int video_id, - int dvdsub_id, char *filename) +static demuxer_t *demux_open_stream(struct MPOpts *opts, stream_t *stream, + int file_format, int force, int audio_id, + int video_id, int dvdsub_id, + char *filename) { demuxer_t *demuxer = NULL; @@ -776,7 +785,7 @@ static demuxer_t *demux_open_stream(stream_t *stream, int file_format, // If somebody requested a demuxer check it if (file_format) { if ((demuxer_desc = get_demuxer_desc_from_type(file_format))) { - demuxer = new_demuxer(stream, demuxer_desc->type, audio_id, + demuxer = new_demuxer(opts, stream, demuxer_desc->type, audio_id, video_id, dvdsub_id, filename); if (demuxer_desc->check_file) fformat = demuxer_desc->check_file(demuxer); @@ -798,8 +807,9 @@ static demuxer_t *demux_open_stream(stream_t *stream, int file_format, } else { // Format changed after check, recurse free_demuxer(demuxer); - return demux_open_stream(stream, fformat, force, audio_id, - video_id, dvdsub_id, filename); + return demux_open_stream(opts, stream, fformat, force, + audio_id, video_id, dvdsub_id, + filename); } } // Check failed for forced demuxer, quit @@ -810,7 +820,7 @@ static demuxer_t *demux_open_stream(stream_t *stream, int file_format, // Test demuxers with safe file checks for (i = 0; (demuxer_desc = demuxer_list[i]); i++) { if (demuxer_desc->safe_check) { - demuxer = new_demuxer(stream, demuxer_desc->type, audio_id, + demuxer = new_demuxer(opts, stream, demuxer_desc->type, audio_id, video_id, dvdsub_id, filename); if ((fformat = demuxer_desc->check_file(demuxer)) != 0) { if (fformat == demuxer_desc->type) { @@ -829,7 +839,7 @@ static demuxer_t *demux_open_stream(stream_t *stream, int file_format, return demuxer; // handled in mplayer.c // Format changed after check, recurse free_demuxer(demuxer); - demuxer = demux_open_stream(stream, fformat, force, + demuxer = demux_open_stream(opts, stream, fformat, force, audio_id, video_id, dvdsub_id, filename); if (demuxer) @@ -851,8 +861,9 @@ static demuxer_t *demux_open_stream(stream_t *stream, int file_format, file_format = demuxer_type_by_filename(filename); if (file_format != DEMUXER_TYPE_UNKNOWN) { // we like recursion :) - demuxer = demux_open_stream(stream, file_format, force, audio_id, - video_id, dvdsub_id, filename); + demuxer = demux_open_stream(opts, stream, file_format, force, + audio_id, video_id, dvdsub_id, + filename); if (demuxer) return demuxer; // done! file_format = DEMUXER_TYPE_UNKNOWN; // continue fuzzy guessing... @@ -863,7 +874,7 @@ static demuxer_t *demux_open_stream(stream_t *stream, int file_format, // Try detection for all other demuxers for (i = 0; (demuxer_desc = demuxer_list[i]); i++) { if (!demuxer_desc->safe_check && demuxer_desc->check_file) { - demuxer = new_demuxer(stream, demuxer_desc->type, audio_id, + demuxer = new_demuxer(opts, stream, demuxer_desc->type, audio_id, video_id, dvdsub_id, filename); if ((fformat = demuxer_desc->check_file(demuxer)) != 0) { if (fformat == demuxer_desc->type) { @@ -882,7 +893,7 @@ static demuxer_t *demux_open_stream(stream_t *stream, int file_format, return demuxer; // handled in mplayer.c // Format changed after check, recurse free_demuxer(demuxer); - demuxer = demux_open_stream(stream, fformat, force, + demuxer = demux_open_stream(opts, stream, fformat, force, audio_id, video_id, dvdsub_id, filename); if (demuxer) @@ -940,8 +951,9 @@ extern int hr_mp3_seek; extern float stream_cache_min_percent; extern float stream_cache_seek_min_percent; -demuxer_t *demux_open(stream_t *vs, int file_format, int audio_id, - int video_id, int dvdsub_id, char *filename) +demuxer_t *demux_open(struct MPOpts *opts, stream_t *vs, int file_format, + int audio_id, int video_id, int dvdsub_id, + char *filename) { stream_t *as = NULL, *ss = NULL; demuxer_t *vd, *ad = NULL, *sd = NULL; @@ -999,7 +1011,7 @@ demuxer_t *demux_open(stream_t *vs, int file_format, int audio_id, } } - vd = demux_open_stream(vs, demuxer_type ? demuxer_type : file_format, + vd = demux_open_stream(opts, vs, demuxer_type ? demuxer_type : file_format, demuxer_force, audio_stream ? -2 : audio_id, video_id, sub_stream ? -2 : dvdsub_id, filename); if (!vd) { @@ -1010,7 +1022,7 @@ demuxer_t *demux_open(stream_t *vs, int file_format, int audio_id, return NULL; } if (as) { - ad = demux_open_stream(as, + ad = demux_open_stream(opts, as, audio_demuxer_type ? audio_demuxer_type : afmt, audio_demuxer_force, audio_id, -2, -2, audio_stream); @@ -1023,7 +1035,8 @@ demuxer_t *demux_open(stream_t *vs, int file_format, int audio_id, hr_mp3_seek = 1; // Enable high res seeking } if (ss) { - sd = demux_open_stream(ss, sub_demuxer_type ? sub_demuxer_type : sfmt, + sd = demux_open_stream(opts, ss, + sub_demuxer_type ? sub_demuxer_type : sfmt, sub_demuxer_force, -2, -2, dvdsub_id, sub_stream); if (!sd) { @@ -1042,10 +1055,11 @@ demuxer_t *demux_open(stream_t *vs, int file_format, int audio_id, else res = vd; - correct_pts = user_correct_pts; - if (correct_pts < 0) - correct_pts = demux_control(res, DEMUXER_CTRL_CORRECT_PTS, NULL) - == DEMUXER_CTRL_OK; + opts->correct_pts = opts->user_correct_pts; + if (opts->correct_pts < 0) + opts->correct_pts = + demux_control(res, DEMUXER_CTRL_CORRECT_PTS, + NULL) == DEMUXER_CTRL_OK; return res; } @@ -1078,9 +1092,8 @@ int demux_seek(demuxer_t *demuxer, float rel_seek_secs, float audio_delay, mp_msg(MSGT_SEEK, MSGL_WARN, MSGTR_CantSeekFile); return 0; } - - demux_flush(demuxer); // clear demux buffers: + demux_flush(demuxer); if (sh_audio) sh_audio->a_buffer_len = 0; @@ -1139,8 +1152,8 @@ int demux_info_add(demuxer_t *demuxer, const char *opt, const char *param) } } - info = demuxer->info = (char **) realloc(info, - (2 * (n + 2)) * sizeof(char *)); + info = demuxer->info = + (char **) realloc(info, (2 * (n + 2)) * sizeof(char *)); info[2 * n] = strdup(opt); info[2 * n + 1] = strdup(param); memset(&info[2 * (n + 1)], 0, 2 * sizeof(char *)); diff --git a/libmpdemux/demuxer.h b/libmpdemux/demuxer.h index 5e4f0858e8..f7f69a9fb7 100644 --- a/libmpdemux/demuxer.h +++ b/libmpdemux/demuxer.h @@ -7,9 +7,8 @@ #include <string.h> #include "stream/stream.h" -#ifdef CONFIG_ASS -#include "libass/ass_types.h" -#endif + +struct MPOpts; #ifdef HAVE_BUILTIN_EXPECT #define likely(x) __builtin_expect ((x) != 0, 1) @@ -20,7 +19,7 @@ #endif #define MAX_PACKS 4096 -#define MAX_PACK_BYTES 0x2000000 +#define MAX_PACK_BYTES 0x8000000 // 128 MiB #define DEMUXER_TYPE_UNKNOWN 0 #define DEMUXER_TYPE_MPEG_ES 1 @@ -101,7 +100,7 @@ #define MP_INPUT_BUFFER_PADDING_SIZE 8 // Holds one packet/frame/whatever -typedef struct demux_packet_st { +typedef struct demux_packet { int len; double pts; double endpts; @@ -110,11 +109,11 @@ typedef struct demux_packet_st { unsigned char* buffer; int flags; // keyframe, etc int refcount; //refcounter for the master packet, if 0, buffer can be free()d - struct demux_packet_st* master; //pointer to the master packet if this one is a cloned one - struct demux_packet_st* next; + struct demux_packet *master; //pointer to the master packet if this one is a cloned one + struct demux_packet *next; } demux_packet_t; -typedef struct { +typedef struct demux_stream { int buffer_pos; // current buffer position int buffer_size; // current buffer size unsigned char* buffer; // current buffer, never free() it, always use free_demux_packet(buffer_ref); @@ -132,7 +131,7 @@ typedef struct { demux_packet_t *last; // append new packets from input stream to here demux_packet_t *current;// needed for refcounting of the buffer int id; // stream ID (for multiple audio/video streams) - struct demuxer_st *demuxer; // parent demuxer structure (stream handler) + struct demuxer *demuxer; // parent demuxer structure (stream handler) // ---- asf ----- demux_packet_t *asf_packet; // read asf fragments here int asf_seq; @@ -142,7 +141,7 @@ typedef struct { void* sh; } demux_stream_t; -typedef struct demuxer_info_st { +typedef struct demuxer_info { char *name; char *author; char *encoder; @@ -154,15 +153,12 @@ typedef struct demuxer_info_st { #define MAX_V_STREAMS 256 #define MAX_S_STREAMS 256 -struct demuxer_st; - -extern int correct_pts; -extern int user_correct_pts; +struct demuxer; /** * Demuxer description structure */ -typedef struct demuxers_desc_st { +typedef struct demuxer_desc { const char *info; ///< What is it (long name and/or description) const char *name; ///< Demuxer name, used with -demuxer switch const char *shortdesc; ///< Description printed at demuxer detection @@ -173,26 +169,26 @@ typedef struct demuxers_desc_st { int safe_check; ///< If 1 detection is safe and fast, do it before file extension check /// Check if can demux the file, return DEMUXER_TYPE_xxx on success - int (*check_file)(struct demuxer_st *demuxer); ///< Mandatory if safe_check == 1, else optional + int (*check_file)(struct demuxer *demuxer); ///< Mandatory if safe_check == 1, else optional /// Get packets from file, return 0 on eof - int (*fill_buffer)(struct demuxer_st *demuxer, demux_stream_t *ds); ///< Mandatory + int (*fill_buffer)(struct demuxer *demuxer, demux_stream_t *ds); ///< Mandatory /// Open the demuxer, return demuxer on success, NULL on failure - struct demuxer_st* (*open)(struct demuxer_st *demuxer); ///< Optional + struct demuxer* (*open)(struct demuxer *demuxer); ///< Optional /// Close the demuxer - void (*close)(struct demuxer_st *demuxer); ///< Optional + void (*close)(struct demuxer *demuxer); ///< Optional // Seek - void (*seek)(struct demuxer_st *demuxer, float rel_seek_secs, float audio_delay, int flags); ///< Optional + void (*seek)(struct demuxer *demuxer, float rel_seek_secs, float audio_delay, int flags); ///< Optional // Control - int (*control)(struct demuxer_st *demuxer, int cmd, void *arg); ///< Optional + int (*control)(struct demuxer *demuxer, int cmd, void *arg); ///< Optional } demuxer_desc_t; -typedef struct demux_chapter_s +typedef struct demux_chapter { uint64_t start, end; char* name; } demux_chapter_t; -typedef struct demux_attachment_s +typedef struct demux_attachment { char* name; char* type; @@ -200,7 +196,7 @@ typedef struct demux_attachment_s unsigned int data_size; } demux_attachment_t; -typedef struct demuxer_st { +typedef struct demuxer { const demuxer_desc_t *desc; ///< Demuxer description structure off_t filepos; // input stream current pos. off_t movi_start; @@ -219,9 +215,9 @@ typedef struct demuxer_st { demux_stream_t *sub; // dvd subtitle buffer/demuxer // stream headers: - void* a_streams[MAX_A_STREAMS]; // audio streams (sh_audio_t) - void* v_streams[MAX_V_STREAMS]; // video sterams (sh_video_t) - void *s_streams[MAX_S_STREAMS]; // dvd subtitles (flag) + struct sh_audio *a_streams[MAX_A_STREAMS]; + struct sh_video *v_streams[MAX_V_STREAMS]; + struct sh_sub *s_streams[MAX_S_STREAMS]; demux_chapter_t* chapters; int num_chapters; @@ -231,6 +227,7 @@ typedef struct demuxer_st { void* priv; // fileformat-dependent data char** info; + struct MPOpts *opts; } demuxer_t; typedef struct { @@ -312,8 +309,8 @@ static inline void *realloc_struct(void *ptr, size_t nmemb, size_t size) { return realloc(ptr, nmemb * size); } -demux_stream_t* new_demuxer_stream(struct demuxer_st *demuxer,int id); -demuxer_t* new_demuxer(stream_t *stream,int type,int a_id,int v_id,int s_id,char *filename); +demux_stream_t* new_demuxer_stream(struct demuxer *demuxer,int id); +demuxer_t* new_demuxer(struct MPOpts *opts, stream_t *stream,int type,int a_id,int v_id,int s_id,char *filename); void free_demuxer_stream(demux_stream_t *ds); void free_demuxer(demuxer_t *demuxer); @@ -376,7 +373,7 @@ static inline int avi_stream_id(unsigned int id){ return a*10+b; } -demuxer_t* demux_open(stream_t *stream,int file_format,int aid,int vid,int sid,char* filename); +demuxer_t* demux_open(struct MPOpts *opts, stream_t *stream,int file_format,int aid,int vid,int sid,char* filename); void demux_flush(demuxer_t *demuxer); int demux_seek(demuxer_t *demuxer,float rel_seek_secs,float audio_delay,int flags); demuxer_t* new_demuxers_demuxer(demuxer_t* vd, demuxer_t* ad, demuxer_t* sd); diff --git a/libmpdemux/mp3_hdr.c b/libmpdemux/mp3_hdr.c index cb59878466..da1826215c 100644 --- a/libmpdemux/mp3_hdr.c +++ b/libmpdemux/mp3_hdr.c @@ -1,6 +1,7 @@ #include <stdio.h> #include "config.h" +#include "mp3_hdr.h" #include "mp_msg.h" //----------------------- mp3 audio frame header parser ----------------------- @@ -19,7 +20,7 @@ static long freqs[9] = { 44100, 48000, 32000, // MPEG 1.0 22050, 24000, 16000, // MPEG 2.0 11025, 12000, 8000}; // MPEG 2.5 -int mp_mp3_get_lsf(unsigned char* hbuf){ +static int mp_mp3_get_lsf(unsigned char* hbuf){ unsigned long newhead = hbuf[0] << 24 | hbuf[1] << 16 | diff --git a/libmpdemux/parse_mp4.c b/libmpdemux/parse_mp4.c index 67ccce5a94..6e4441a17c 100644 --- a/libmpdemux/parse_mp4.c +++ b/libmpdemux/parse_mp4.c @@ -36,7 +36,7 @@ #define MP4_DL MSGL_V #define freereturn(a,b) free(a); return b -int mp4_read_descr_len(stream_t *s) { +static int mp4_read_descr_len(stream_t *s) { uint8_t b; uint8_t numBytes = 0; uint32_t length = 0; diff --git a/libmpdemux/stheader.h b/libmpdemux/stheader.h index 07ecfaeded..67fa0e1fb4 100644 --- a/libmpdemux/stheader.h +++ b/libmpdemux/stheader.h @@ -1,16 +1,17 @@ #ifndef MPLAYER_STHEADER_H #define MPLAYER_STHEADER_H -#include "demuxer.h" #include "aviheader.h" #include "ms_hdr.h" +struct MPOpts; // Stream headers: -typedef struct { +typedef struct sh_audio { + struct MPOpts *opts; int aid; - demux_stream_t *ds; - struct codecs_st *codec; + struct demux_stream *ds; + struct codecs *codec; unsigned int format; int initialized; float stream_delay; // number of seconds stream should be delayed (according to dwStart or similar) @@ -36,8 +37,8 @@ typedef struct { int a_out_buffer_len; int a_out_buffer_size; // void* audio_out; // the audio_out handle, used for this audio stream - struct af_stream_s *afilter; // the audio filter stream - struct ad_functions_s* ad_driver; + struct af_stream *afilter; // the audio filter stream + struct ad_functions *ad_driver; #ifdef CONFIG_DYNAMIC_PLUGINS void *dec_handle; #endif @@ -54,10 +55,11 @@ typedef struct { int default_track; } sh_audio_t; -typedef struct { +typedef struct sh_video { + struct MPOpts *opts; int vid; - demux_stream_t *ds; - struct codecs_st *codec; + struct demux_stream *ds; + struct codecs *codec; unsigned int format; int initialized; float timer; // absolute time in video stream, since last start/seek @@ -81,7 +83,9 @@ typedef struct { int disp_w,disp_h; // display size (filled by fileformat parser) // output driver/filters: (set by libmpcodecs core) unsigned int outfmtidx; - struct vf_instance_s *vfilter; // the video filter chain, used for this video stream + struct vf_instance *vfilter; // the video filter chain, used for this video stream + int output_flags; // query_format() results for output filters+vo + const struct vd_functions *vd_driver; int vf_initialized; #ifdef CONFIG_DYNAMIC_PLUGINS void *dec_handle; @@ -94,14 +98,13 @@ typedef struct { void* context; // codec-specific stuff (usually HANDLE or struct pointer) } sh_video_t; -typedef struct { +typedef struct sh_sub { + struct MPOpts *opts; int sid; char type; // t = text, v = VobSub, a = SSA/ASS unsigned char* extradata; // extra header data passed from demuxer int extradata_len; -#ifdef CONFIG_ASS - ass_track_t* ass_track; // for SSA/ASS streams (type == 'a') -#endif + struct ass_track_s *ass_track; // for SSA/ASS streams (type == 'a') char* lang; // track language int default_track; } sh_sub_t; diff --git a/libvo/aspect.c b/libvo/aspect.c index e54e8deb43..367cdec076 100644 --- a/libvo/aspect.c +++ b/libvo/aspect.c @@ -19,9 +19,11 @@ /* Stuff for correct aspect scaling. */ #include "aspect.h" #include "geometry.h" +#include "video_out.h" //#ifndef ASPECT_TEST #include "mp_msg.h" #include "help_mp.h" +#include "options.h" //#endif //#define ASPECT_DEBUG @@ -30,80 +32,66 @@ #include <stdio.h> #endif -int vo_panscan_x = 0; -int vo_panscan_y = 0; -float vo_panscan_amount = 0; -float vo_panscanrange = 1.0; - #include "video_out.h" -float force_monitor_aspect=0; -float monitor_aspect=0; -float monitor_pixel_aspect=1; -extern float movie_aspect; - -static struct { - int orgw; // real width - int orgh; // real height - int prew; // prescaled width - int preh; // prescaled height - int scrw; // horizontal resolution - int scrh; // vertical resolution - float asp; -} aspdat; - -void aspect_save_orig(int orgw, int orgh){ +void aspect_save_orig(struct vo *vo, int orgw, int orgh) +{ #ifdef ASPECT_DEBUG printf("aspect_save_orig %dx%d \n",orgw,orgh); #endif - aspdat.orgw = orgw; - aspdat.orgh = orgh; + vo->aspdat.orgw = orgw; + vo->aspdat.orgh = orgh; } -void aspect_save_prescale(int prew, int preh){ +void aspect_save_prescale(struct vo *vo, int prew, int preh) +{ #ifdef ASPECT_DEBUG printf("aspect_save_prescale %dx%d \n",prew,preh); #endif - aspdat.prew = prew; - aspdat.preh = preh; + vo->aspdat.prew = prew; + vo->aspdat.preh = preh; } -void aspect_save_screenres(int scrw, int scrh){ +void aspect_save_screenres(struct vo *vo, int scrw, int scrh) +{ #ifdef ASPECT_DEBUG printf("aspect_save_screenres %dx%d \n",scrw,scrh); #endif - aspdat.scrw = scrw; - aspdat.scrh = scrh; - if (force_monitor_aspect) - monitor_aspect = force_monitor_aspect; - else - monitor_aspect = monitor_pixel_aspect * scrw / scrh; + struct MPOpts *opts = vo->opts; + vo->aspdat.scrw = scrw; + vo->aspdat.scrh = scrh; + if (opts->force_monitor_aspect) + vo->monitor_aspect = opts->force_monitor_aspect; + else + vo->monitor_aspect = opts->monitor_pixel_aspect * scrw / scrh; } /* aspect is called with the source resolution and the * resolution, that the scaled image should fit into */ -void aspect_fit(int *srcw, int *srch, int fitw, int fith){ +void aspect_fit(struct vo *vo, int *srcw, int *srch, int fitw, int fith) +{ + struct aspect_data *aspdat = &vo->aspdat; int tmpw; #ifdef ASPECT_DEBUG - printf("aspect(0) fitin: %dx%d screenaspect: %.2f\n",aspdat.scrw,aspdat.scrh, + printf("aspect(0) fitin: %dx%d screenaspect: %.2f\n",aspdat->scrw,aspdat->scrh, monitor_aspect); - printf("aspect(1) wh: %dx%d (org: %dx%d)\n",*srcw,*srch,aspdat.prew,aspdat.preh); + printf("aspect(1) wh: %dx%d (org: %dx%d)\n",*srcw,*srch,aspdat->prew,aspdat->preh); #endif *srcw = fitw; - *srch = (int)(((float)fitw / (float)aspdat.prew * (float)aspdat.preh) - * ((float)aspdat.scrh / ((float)aspdat.scrw / monitor_aspect))); + *srch = (int)(((float)fitw / (float)aspdat->prew * (float)aspdat->preh) + * ((float)aspdat->scrh / ((float)aspdat->scrw / vo->monitor_aspect))); *srch+= *srch%2; // round #ifdef ASPECT_DEBUG - printf("aspect(2) wh: %dx%d (org: %dx%d)\n",*srcw,*srch,aspdat.prew,aspdat.preh); + printf("aspect(2) wh: %dx%d (org: %dx%d)\n",*srcw,*srch,aspdat->prew,aspdat->preh); #endif - if(*srch>aspdat.scrh || *srch<aspdat.orgh){ - tmpw = (int)(((float)fith / (float)aspdat.preh * (float)aspdat.prew) - * ((float)aspdat.scrw / ((float)aspdat.scrh / (1.0/monitor_aspect)))); + if(*srch>aspdat->scrh || *srch<aspdat->orgh){ + tmpw = (int)(((float)fith / (float)aspdat->preh * (float)aspdat->prew) + * ((float)aspdat->scrw / ((float)aspdat->scrh / (1.0/vo->monitor_aspect)))); tmpw+= tmpw%2; // round - if(tmpw<=aspdat.scrw /*&& tmpw>=aspdat.orgw*/){ + if(tmpw<=aspdat->scrw /*&& tmpw>=aspdat->orgw*/){ *srch = fith; *srcw = tmpw; }else{ @@ -114,47 +102,48 @@ void aspect_fit(int *srcw, int *srch, int fitw, int fith){ #endif } } - aspdat.asp=*srcw / (float)*srch; + aspdat->asp=*srcw / (float)*srch; #ifdef ASPECT_DEBUG - printf("aspect(3) wh: %dx%d (org: %dx%d)\n",*srcw,*srch,aspdat.prew,aspdat.preh); + printf("aspect(3) wh: %dx%d (org: %dx%d)\n",*srcw,*srch,aspdat->prew,aspdat->preh); #endif } -void aspect(int *srcw, int *srch, int zoom){ - int fitw = zoom ? aspdat.scrw : aspdat.prew; - int fith = zoom ? aspdat.scrh : aspdat.preh; +void aspect(struct vo *vo, int *srcw, int *srch, int zoom){ + int fitw = zoom ? vo->aspdat.scrw : vo->aspdat.prew; + int fith = zoom ? vo->aspdat.scrh : vo->aspdat.preh; if( !zoom && geometry_wh_changed ) { #ifdef ASPECT_DEBUG printf("aspect(0) no aspect forced!\n"); #endif return; // the user doesn't want to fix aspect } - aspect_fit(srcw, srch, fitw, fith); + aspect_fit(vo, srcw, srch, fitw, fith); } -void panscan_init( void ) +void panscan_init(struct vo *vo) { - vo_panscan_x=0; - vo_panscan_y=0; - vo_panscan_amount=0.0f; + vo->panscan_x = 0; + vo->panscan_y = 0; + vo->panscan_amount = 0.0f; } -void panscan_calc( void ) +void panscan_calc(struct vo *vo) { int fwidth,fheight; int vo_panscan_area; - - if (vo_panscanrange > 0) { - aspect(&fwidth,&fheight,A_ZOOM); - vo_panscan_area = (aspdat.scrh-fheight); - if (!vo_panscan_area) - vo_panscan_area = aspdat.scrw - fwidth; - vo_panscan_area *= vo_panscanrange; - } else - vo_panscan_area = -vo_panscanrange * aspdat.scrh; - - vo_panscan_amount = vo_fs ? vo_panscan : 0; - vo_panscan_x = vo_panscan_area * vo_panscan_amount * aspdat.asp; - vo_panscan_y = vo_panscan_area * vo_panscan_amount; + struct MPOpts *opts = vo->opts; + + if (opts->vo_panscanrange > 0) { + aspect(vo, &fwidth, &fheight, A_ZOOM); + vo_panscan_area = (vo->aspdat.scrh - fheight); + if (!vo_panscan_area) + vo_panscan_area = vo->aspdat.scrw - fwidth; + vo_panscan_area *= opts->vo_panscanrange; + } else + vo_panscan_area = -opts->vo_panscanrange * vo->aspdat.scrh; + + vo->panscan_amount = vo_fs ? vo_panscan : 0; + vo->panscan_x = vo_panscan_area * vo->panscan_amount * vo->aspdat.asp; + vo->panscan_y = vo_panscan_area * vo->panscan_amount; } diff --git a/libvo/aspect.h b/libvo/aspect.h index 0c741d4ae3..89839e2c94 100644 --- a/libvo/aspect.h +++ b/libvo/aspect.h @@ -20,23 +20,35 @@ #define MPLAYER_ASPECT_H /* Stuff for correct aspect scaling. */ -extern int vo_panscan_x; -extern int vo_panscan_y; -extern float vo_panscan_amount; +struct vo; +void panscan_init(struct vo *vo); +void panscan_calc(struct vo *vo); -void panscan_init(void); -void panscan_calc(void); +void aspect_save_orig(struct vo *vo, int orgw, int orgh); -void aspect_save_orig(int orgw, int orgh); +void aspect_save_prescale(struct vo *vo, int prew, int preh); -void aspect_save_prescale(int prew, int preh); - -void aspect_save_screenres(int scrw, int scrh); +void aspect_save_screenres(struct vo *vo, int scrw, int scrh); #define A_ZOOM 1 #define A_NOZOOM 0 -void aspect(int *srcw, int *srch, int zoom); -void aspect_fit(int *srcw, int *srch, int fitw, int fith); +void aspect(struct vo *vo, int *srcw, int *srch, int zoom); +void aspect_fit(struct vo *vo, int *srcw, int *srch, int fitw, int fith); + + +#ifdef IS_OLD_VO +#define vo_panscan_x global_vo->panscan_x +#define vo_panscan_y global_vo->panscan_y +#define vo_panscan_amount global_vo->panscan_amount +#define monitor_aspect global_vo->monitor_aspect + +#define panscan_init() panscan_init(global_vo) +#define panscan_calc() panscan_calc(global_vo) +#define aspect_save_orig(...) aspect_save_orig(global_vo, __VA_ARGS__) +#define aspect_save_prescale(...) aspect_save_prescale(global_vo, __VA_ARGS__) +#define aspect_save_screenres(...) aspect_save_screenres(global_vo, __VA_ARGS__) +#define aspect(...) aspect(global_vo, __VA_ARGS__) +#endif #endif /* MPLAYER_ASPECT_H */ diff --git a/libvo/font_load.h b/libvo/font_load.h index 5371b54cbf..c945d11277 100644 --- a/libvo/font_load.h +++ b/libvo/font_load.h @@ -80,7 +80,6 @@ typedef struct font_desc { } font_desc_t; extern font_desc_t* vo_font; -extern font_desc_t* sub_font; extern char *subtitle_font_encoding; extern float text_font_scale_factor; diff --git a/libvo/font_load_ft.c b/libvo/font_load_ft.c index ddb6af5ada..ac9bcbfa75 100644 --- a/libvo/font_load_ft.c +++ b/libvo/font_load_ft.c @@ -84,13 +84,13 @@ static FT_Library library; #define OSD_CHARSET_SIZE 15 -static FT_ULong osd_charset[OSD_CHARSET_SIZE] = +static const FT_ULong osd_charset[OSD_CHARSET_SIZE] = { 0xe001, 0xe002, 0xe003, 0xe004, 0xe005, 0xe006, 0xe007, 0xe008, 0xe009, 0xe00a, 0xe00b, 0xe010, 0xe011, 0xe012, 0xe013 }; -static FT_ULong osd_charcodes[OSD_CHARSET_SIZE] = +static const FT_ULong osd_charcodes[OSD_CHARSET_SIZE] = { 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08, 0x09,0x0a,0x0b,0x10,0x11,0x12,0x13 diff --git a/libvo/gl_common.c b/libvo/gl_common.c index 596f99c0b9..b65023f93e 100644 --- a/libvo/gl_common.c +++ b/libvo/gl_common.c @@ -32,6 +32,7 @@ #include <string.h> #include <ctype.h> #include <math.h> +#include "old_vo_defines.h" #include "gl_common.h" #include "libavutil/common.h" diff --git a/libvo/gl_common.h b/libvo/gl_common.h index 6f9ec6f1e3..978866e340 100644 --- a/libvo/gl_common.h +++ b/libvo/gl_common.h @@ -353,18 +353,18 @@ void glDisableYUVConversion(GLenum target, int type); /** \} */ #ifdef GL_WIN32 -#define vo_border() vo_w32_border() +#define vo_gl_border(vo) vo_w32_border() #define vo_check_events() vo_w32_check_events() #define vo_fullscreen() vo_w32_fullscreen() -#define vo_ontop() vo_w32_ontop() +#define vo_gl_ontop() vo_w32_ontop() #define vo_uninit() vo_w32_uninit() int setGlWindow(int *vinfo, HGLRC *context, HWND win); void releaseGlContext(int *vinfo, HGLRC *context); #else -#define vo_border() vo_x11_border() +#define vo_gl_border(vo) vo_x11_border(vo) #define vo_check_events() vo_x11_check_events(mDisplay) #define vo_fullscreen() vo_x11_fullscreen() -#define vo_ontop() vo_x11_ontop() +#define vo_gl_ontop() vo_x11_ontop() #define vo_uninit() vo_x11_uninit() int setGlWindow(XVisualInfo **vinfo, GLXContext *context, Window win); void releaseGlContext(XVisualInfo **vinfo, GLXContext *context); diff --git a/libvo/mga_common.c b/libvo/mga_common.c index 69c8f6322d..06d374f9fd 100644 --- a/libvo/mga_common.c +++ b/libvo/mga_common.c @@ -23,6 +23,7 @@ #include "libmpcodecs/vf_scale.h" #include "mp_msg.h" #include "help_mp.h" +#include "old_vo_wrapper.h" // mga_vid drawing functions static void set_window( void ); /* forward declaration to kill warnings */ @@ -246,7 +247,7 @@ static void mga_fullscreen(void) } #endif -static int control(uint32_t request, void *data, ...) +static int control(uint32_t request, void *data) { switch (request) { case VOCTRL_QUERY_FORMAT: @@ -257,11 +258,12 @@ static int control(uint32_t request, void *data, ...) return draw_image(data); case VOCTRL_SET_EQUALIZER: { - va_list ap; short value; uint32_t luma,prev; + struct voctrl_set_equalizer_args *args = data; - if ( strcmp( data,"brightness" ) && strcmp( data,"contrast" ) ) return VO_FALSE; + if (strcmp(args->name, "brightness") && strcmp(args->name, "contrast")) + return VO_FALSE; if (ioctl(f,MGA_VID_GET_LUMA,&prev)) { perror("Error in mga_vid_config ioctl()"); @@ -271,15 +273,13 @@ static int control(uint32_t request, void *data, ...) // printf("GET: 0x%4X 0x%4X \n",(prev>>16),(prev&0xffff)); - va_start(ap, data); - value = va_arg(ap, int); - va_end(ap); + value = args->value; // printf("value: %d -> ",value); value=((value+100)*255)/200-128; // maps -100=>-128 and +100=>127 // printf("%d \n",value); - if(!strcmp(data,"contrast")) + if (!strcmp(args->name, "contrast")) luma = (prev&0xFFFF0000)|(value&0xFFFF); else luma = (prev&0xFFFF)|(value<<16); @@ -295,12 +295,12 @@ static int control(uint32_t request, void *data, ...) case VOCTRL_GET_EQUALIZER: { - va_list ap; - int * value; short val; uint32_t luma; + struct voctrl_get_equalizer_args *args = data; - if ( strcmp( data,"brightness" ) && strcmp( data,"contrast" ) ) return VO_FALSE; + if (strcmp(args->name, "brightness") && strcmp(args->name, "contrast")) + return VO_FALSE; if (ioctl(f,MGA_VID_GET_LUMA,&luma)) { perror("Error in mga_vid_config ioctl()"); @@ -308,16 +308,12 @@ static int control(uint32_t request, void *data, ...) return VO_FALSE; } - if ( !strcmp( data,"contrast" ) ) + if (!strcmp(args->name, "contrast")) val=(luma & 0xFFFF); else val=(luma >> 16); - va_start(ap, data); - value = va_arg(ap, int*); - va_end(ap); - - *value = (val*200)/255; + *args->valueptr = (val*200)/255; return VO_TRUE; } diff --git a/libvo/old_vo_defines.h b/libvo/old_vo_defines.h new file mode 100644 index 0000000000..feded12d5b --- /dev/null +++ b/libvo/old_vo_defines.h @@ -0,0 +1,24 @@ +#ifndef MPLAYER_OLD_VO_DEFINES_H +#define MPLAYER_OLD_VO_DEFINES_H + +#include "options.h" +#include "video_out.h" +#include "old_vo_wrapper.h" + +// Triggers more defines in x11_common.h +#define IS_OLD_VO 1 + +#define vo_ontop global_vo->opts->vo_ontop +#define vo_config_count global_vo->config_count +#define vo_dx global_vo->dx +#define vo_dy global_vo->dy +#define vo_dwidth global_vo->dwidth +#define vo_dheight global_vo->dheight +#define vo_dbpp global_vo->opts->vo_dbpp +#define vo_screenwidth global_vo->opts->vo_screenwidth +#define vo_screenheight global_vo->opts->vo_screenheight +#define vidmode global_vo->opts->vidmode +#define movie_aspect global_vo->opts->movie_aspect + +#define calc_src_dst_rects(...) calc_src_dst_rects(global_vo, __VA_ARGS__) +#endif diff --git a/libvo/old_vo_wrapper.c b/libvo/old_vo_wrapper.c new file mode 100644 index 0000000000..bdbc8b8349 --- /dev/null +++ b/libvo/old_vo_wrapper.c @@ -0,0 +1,116 @@ +/* + * This file is part of MPlayer. + * + * MPlayer 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. + * + * MPlayer 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 MPlayer; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + + +#include <stdint.h> +#include "old_vo_wrapper.h" +#include "video_out.h" +#include "sub.h" + +struct vo *global_vo; +struct osd_state *global_osd; + +int old_vo_preinit(struct vo *vo, const char *arg) +{ + global_vo = vo; + return vo->driver->old_functions->preinit(arg); +} + + +int old_vo_config(struct vo *vo, uint32_t width, uint32_t height, + uint32_t d_width, uint32_t d_height, + uint32_t flags, char *title, uint32_t format) +{ + return vo->driver->old_functions->config(width, height, d_width, + d_height, flags, title, format); +} + + +int old_vo_control(struct vo *vo, uint32_t request, void *data) +{ + return vo->driver->old_functions->control(request, data); +} + + +int old_vo_draw_frame(struct vo *vo, uint8_t *src[]) +{ + return vo->driver->old_functions->draw_frame(src); +} + + +int old_vo_draw_slice(struct vo *vo, uint8_t *src[], int stride[], + int w, int h, int x, int y) +{ + return vo->driver->old_functions->draw_slice(src, stride, w, h, x, y); +} + + +void old_vo_draw_osd(struct vo *vo, struct osd_state *osd) +{ + global_osd = osd; + vo->driver->old_functions->draw_osd(); +} + + +void old_vo_flip_page(struct vo *vo) +{ + vo->driver->old_functions->flip_page(); +} + + +void old_vo_check_events(struct vo *vo) +{ + vo->driver->old_functions->check_events(); +} + + +void old_vo_uninit(struct vo *vo) +{ + vo->driver->old_functions->uninit(); +} + + +static void draw_alpha_wrapper(void *ctx, int x0, int y0, int w, int h, + unsigned char *src, unsigned char *srca, + int stride) +{ + void (*draw_alpha)(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride) = ctx; + draw_alpha(x0, y0, w, h, src, srca, stride); +} + + +void vo_draw_text(int dxs,int dys,void (*draw_alpha)(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride)) +{ + osd_draw_text(global_osd, dxs, dys, draw_alpha_wrapper, draw_alpha); +} + +void vo_draw_text_ext(int dxs, int dys, int left_border, int top_border, + int right_border, int bottom_border, int orig_w, int orig_h, + void (*draw_alpha)(int x0, int y0, int w,int h, + unsigned char* src, + unsigned char *srca, int stride)) +{ + osd_draw_text_ext(global_osd, dxs, dys, left_border, top_border, + right_border, bottom_border, orig_w, orig_h, + draw_alpha_wrapper, draw_alpha); +} + +int vo_update_osd(int dxs, int dys) +{ + return osd_update(global_osd, dxs, dys); +} diff --git a/libvo/old_vo_wrapper.h b/libvo/old_vo_wrapper.h new file mode 100644 index 0000000000..250a1187fe --- /dev/null +++ b/libvo/old_vo_wrapper.h @@ -0,0 +1,29 @@ +#ifndef MPLAYER_OLD_VO_WRAPPER_H +#define MPLAYER_OLD_VO_WRAPPER_H + +#include <stdint.h> +#include "video_out.h" + +extern struct vo *global_vo; +extern struct osd_state *global_osd; + +int old_vo_preinit(struct vo *vo, const char *); +int old_vo_config(struct vo *vo, uint32_t width, uint32_t height, + uint32_t d_width, uint32_t d_height, + uint32_t flags, char *title, uint32_t format); +int old_vo_control(struct vo *vo, uint32_t request, void *data); +int old_vo_draw_frame(struct vo *vo, uint8_t *src[]); +int old_vo_draw_slice(struct vo *vo, uint8_t *src[], int stride[], + int w, int h, int x, int y); +void old_vo_draw_osd(struct vo *vo, struct osd_state *osd); +void old_vo_flip_page(struct vo *vo); +void old_vo_check_events(struct vo *vo); +void old_vo_uninit(struct vo *vo); + +void vo_draw_text(int dxs,int dys,void (*draw_alpha)(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride)); +void vo_draw_text_ext(int dxs, int dys, int left_border, int top_border, + int right_border, int bottom_border, int orig_w, int orig_h, + void (*draw_alpha)(int x0, int y0, int w,int h,unsigned char* src, unsigned char *srca, int stride)); +int vo_update_osd(int dxs, int dys); + +#endif diff --git a/libvo/spuenc.c b/libvo/spuenc.c index 41303aee3f..a1e457c282 100644 --- a/libvo/spuenc.c +++ b/libvo/spuenc.c @@ -229,50 +229,3 @@ pixbuf_encode_rle(int x, int y, int w, int h, char *inbuf, int stride,encodedat } encode_do_control(x,y, ed, &pb); } - - -void -pixbuf_load_xpm( pixbuf* pb, char* xpm[] ) { - int colors, chrs, l, n; - char c[4], table[256]; - unsigned char *b, *i; - - sscanf( xpm[0], "%d %d %d %d", &pb->x, &pb->y, &colors, &chrs); - if( colors > 4 ) { - fprintf( stderr, "the pixmap MUST be 4 colors or less\n"); - exit (-1); - } - if( chrs != 1 ) { - fprintf( stderr, "the XPM format MUST be 1 char per pixel\n"); - exit (-1); - } - if( pb->x > 0xFFF || pb->y > 0xFFF ) { - fprintf( stderr, "the size is excesive\n"); - exit (-1); - } - - for( l=0; l<colors; l++ ) { - n= sscanf( xpm[l+1], "%c c #%x", &c[l], &pb->rgb[l]); - if( n < 2 ) { - /* this one is transparent */ - pb->rgb[l]=0xff000000; - } - table[(int)c[l]]=l; - } - - pb->pixels= malloc( pb->x * pb->y ); - b= pb->pixels; - - for( l= colors+1; l <= pb->y + colors; l++ ) { - i= xpm[l]; - while( (int)*i) { - *b++ = table[*i++]; - } - } -} - -void -pixbuf_delete( pixbuf* pb ) { - free( pb->pixels ); -} - diff --git a/libvo/spuenc.h b/libvo/spuenc.h index 5f27680876..d19732a98f 100644 --- a/libvo/spuenc.h +++ b/libvo/spuenc.h @@ -41,6 +41,5 @@ typedef struct { } encodedata; void pixbuf_encode_rle(int x, int y, int w, int h, char *inbuf, int stride, encodedata *ed); -void pixbuf_delete(pixbuf* pb); #endif /* MPLAYER_SPUENC_H */ diff --git a/libvo/sub.c b/libvo/sub.c index cfd88ef9d8..47bfdac2e8 100644 --- a/libvo/sub.c +++ b/libvo/sub.c @@ -32,6 +32,7 @@ #include "stream/tv.h" #include "osdep/timer.h" +#include "talloc.h" #include "mplayer.h" #include "mp_msg.h" #include "help_mp.h" @@ -64,7 +65,7 @@ struct osd_text_p { }; //^ -char * sub_osd_names[]={ +char * const sub_osd_names[]={ MSGTR_VO_SUB_Seekbar, MSGTR_VO_SUB_Play, MSGTR_VO_SUB_Pause, @@ -79,13 +80,11 @@ char * sub_osd_names[]={ MSGTR_VO_SUB_Hue, MSGTR_VO_SUB_Balance }; -char * sub_osd_names_short[] ={ "", "|>", "||", "[]", "<<" , ">>", "", "", "", "", "", "", "" }; +char * const sub_osd_names_short[] ={ "", "|>", "||", "[]", "<<" , ">>", "", "", "", "", "", "", "" }; //static int vo_font_loaded=-1; font_desc_t* vo_font=NULL; -font_desc_t* sub_font=NULL; -unsigned char* vo_osd_text=NULL; #ifdef CONFIG_TV_TELETEXT void* vo_osd_teletext_page=NULL; int vo_osd_teletext_half = 0; @@ -167,9 +166,11 @@ static void alloc_buf(mp_osd_obj_t* obj) } // renders the buffer -inline static void vo_draw_text_from_buffer(mp_osd_obj_t* obj,void (*draw_alpha)(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride)){ +inline static void vo_draw_text_from_buffer(mp_osd_obj_t* obj,void (*draw_alpha)(void *ctx, int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride), void *ctx) +{ if (obj->allocated > 0) { - draw_alpha(obj->bbox.x1,obj->bbox.y1, + draw_alpha(ctx, + obj->bbox.x1,obj->bbox.y1, obj->bbox.x2-obj->bbox.x1, obj->bbox.y2-obj->bbox.y1, obj->bitmap_buffer, @@ -192,8 +193,10 @@ no_utf8: return c; } -inline static void vo_update_text_osd(mp_osd_obj_t* obj,int dxs,int dys){ - const char *cp=vo_osd_text; +inline static void vo_update_text_osd(struct osd_state *osd, mp_osd_obj_t* obj, + int dxs, int dys) +{ + const char *cp = osd->osd_text; int x=20; int h=0; int font; @@ -214,7 +217,7 @@ inline static void vo_update_text_osd(mp_osd_obj_t* obj,int dxs,int dys){ alloc_buf(obj); - cp=vo_osd_text; + cp = osd->osd_text; x = obj->x; while (*cp){ uint16_t c=utf8_get_char(&cp); @@ -669,7 +672,7 @@ inline static void vo_update_text_progbar(mp_osd_obj_t* obj,int dxs,int dys){ subtitle* vo_sub=NULL; -inline static void vo_update_text_sub(mp_osd_obj_t* obj,int dxs,int dys){ +inline static void vo_update_text_sub(struct osd_state *osd, mp_osd_obj_t* obj,int dxs,int dys){ unsigned char *t; int c,i,j,l,x,y,font,prevc,counter; int k; @@ -678,10 +681,11 @@ inline static void vo_update_text_sub(mp_osd_obj_t* obj,int dxs,int dys){ int xmin=dxs,xmax=0; int h,lasth; int xtblc, utblc; + struct font_desc *sub_font = osd->sub_font; obj->flags|=OSDFLAG_CHANGED|OSDFLAG_VISIBLE; - if(!vo_sub || !sub_font || !sub_visibility || (sub_font->font[40]<0)){ + if(!vo_sub || !osd->sub_font || !sub_visibility || (sub_font->font[40]<0)){ obj->flags&=~OSDFLAG_VISIBLE; return; } @@ -1052,9 +1056,9 @@ inline static void vo_update_spudec_sub(mp_osd_obj_t* obj, int dxs, int dys) obj->flags |= OSDFLAG_BBOX; } -inline static void vo_draw_spudec_sub(mp_osd_obj_t* obj, void (*draw_alpha)(int x0, int y0, int w, int h, unsigned char* src, unsigned char* srca, int stride)) +inline static void vo_draw_spudec_sub(mp_osd_obj_t* obj, void (*draw_alpha)(void *ctx, int x0, int y0, int w, int h, unsigned char* src, unsigned char* srca, int stride), void *ctx) { - spudec_draw_scaled(vo_spudec, obj->dxs, obj->dys, draw_alpha); + spudec_draw_scaled(vo_spudec, obj->dxs, obj->dys, draw_alpha, ctx); } void *vo_spudec=NULL; @@ -1078,7 +1082,8 @@ static mp_osd_obj_t* new_osd_obj(int type){ return osd; } -void free_osd_list(void){ +void osd_free(struct osd_state *osd) +{ mp_osd_obj_t* obj=vo_osd_list; while(obj){ mp_osd_obj_t* next=obj->next; @@ -1088,12 +1093,15 @@ void free_osd_list(void){ obj=next; } vo_osd_list=NULL; + talloc_free(osd); } #define FONT_LOAD_DEFER 6 -int vo_update_osd_ext(int dxs,int dys, int left_border, int top_border, - int right_border, int bottom_border, int orig_w, int orig_h){ +int osd_update_ext(struct osd_state *osd, int dxs, int dys, int left_border, + int top_border, int right_border, int bottom_border, + int orig_w, int orig_h) +{ mp_osd_obj_t* obj=vo_osd_list; int chg=0; #ifdef CONFIG_FREETYPE @@ -1123,20 +1131,20 @@ int vo_update_osd_ext(int dxs,int dys, int left_border, int top_border, force_load_font = 0; load_font_ft(dxs, dys, &vo_font, font_name, osd_font_scale_factor); if (sub_font_name) - load_font_ft(dxs, dys, &sub_font, sub_font_name, text_font_scale_factor); + load_font_ft(dxs, dys, &osd->sub_font, sub_font_name, text_font_scale_factor); else - load_font_ft(dxs, dys, &sub_font, font_name, text_font_scale_factor); + load_font_ft(dxs, dys, &osd->sub_font, font_name, text_font_scale_factor); prev_dxs = dxs; prev_dys = dys; defer_counter = 0; } else { if (!vo_font) load_font_ft(dxs, dys, &vo_font, font_name, osd_font_scale_factor); - if (!sub_font) { + if (!osd->sub_font) { if (sub_font_name) - load_font_ft(dxs, dys, &sub_font, sub_font_name, text_font_scale_factor); + load_font_ft(dxs, dys, &osd->sub_font, sub_font_name, text_font_scale_factor); else - load_font_ft(dxs, dys, &sub_font, font_name, text_font_scale_factor); + load_font_ft(dxs, dys, &osd->sub_font, font_name, text_font_scale_factor); } } #endif @@ -1152,7 +1160,7 @@ int vo_update_osd_ext(int dxs,int dys, int left_border, int top_border, break; #endif case OSDTYPE_SUBTITLE: - vo_update_text_sub(obj,dxs,dys); + vo_update_text_sub(osd, obj,dxs,dys); break; #ifdef CONFIG_TV_TELETEXT case OSDTYPE_TELETEXT: @@ -1171,8 +1179,8 @@ int vo_update_osd_ext(int dxs,int dys, int left_border, int top_border, obj->flags&=~OSDFLAG_VISIBLE; break; case OSDTYPE_OSD: - if(vo_font && vo_osd_text && vo_osd_text[0]){ - vo_update_text_osd(obj,dxs,dys); // update bbox + if(vo_font && osd->osd_text[0]){ + vo_update_text_osd(osd, obj, dxs, dys); // update bbox obj->flags|=OSDFLAG_VISIBLE|OSDFLAG_CHANGED; } else obj->flags&=~OSDFLAG_VISIBLE; @@ -1212,16 +1220,20 @@ int vo_update_osd_ext(int dxs,int dys, int left_border, int top_border, return chg; } -int vo_update_osd(int dxs, int dys) { - return vo_update_osd_ext(dxs, dys, 0, 0, 0, 0, dxs, dys); +int osd_update(struct osd_state *osd, int dxs, int dys) +{ + return osd_update_ext(osd, dxs, dys, 0, 0, 0, 0, dxs, dys); } -void vo_init_osd(void){ +struct osd_state *osd_create(void) +{ + struct osd_state *osd = talloc_zero(NULL, struct osd_state); + *osd = (struct osd_state){ + }; if(!draw_alpha_init_flag){ draw_alpha_init_flag=1; vo_draw_alpha_init(); } - if(vo_osd_list) free_osd_list(); // temp hack, should be moved to mplayer/mencoder later new_osd_obj(OSDTYPE_OSD); new_osd_obj(OSDTYPE_SUBTITLE); @@ -1236,13 +1248,16 @@ void vo_init_osd(void){ #ifdef CONFIG_FREETYPE force_load_font = 1; #endif + return osd; } int vo_osd_changed_flag=0; -void vo_remove_text(int dxs,int dys,void (*remove)(int x0,int y0, int w,int h)){ +void osd_remove_text(struct osd_state *osd, int dxs, int dys, + void (*remove)(int x0, int y0, int w, int h)) +{ mp_osd_obj_t* obj=vo_osd_list; - vo_update_osd(dxs,dys); + osd_update(osd, dxs, dys); while(obj){ if(((obj->flags&OSDFLAG_CHANGED) || (obj->flags&OSDFLAG_VISIBLE)) && (obj->flags&OSDFLAG_OLD_BBOX)){ @@ -1258,17 +1273,24 @@ void vo_remove_text(int dxs,int dys,void (*remove)(int x0,int y0, int w,int h)){ } } -void vo_draw_text_ext(int dxs, int dys, int left_border, int top_border, - int right_border, int bottom_border, int orig_w, int orig_h, - void (*draw_alpha)(int x0, int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride)) { +void osd_draw_text_ext(struct osd_state *osd, int dxs, int dys, + int left_border, int top_border, int right_border, + int bottom_border, int orig_w, int orig_h, + void (*draw_alpha)(void *ctx, int x0, int y0, int w, + int h, unsigned char* src, + unsigned char *srca, + int stride), + void *ctx) +{ mp_osd_obj_t* obj=vo_osd_list; - vo_update_osd_ext(dxs, dys, left_border, top_border, right_border, bottom_border, orig_w, orig_h); + osd_update_ext(osd, dxs, dys, left_border, top_border, right_border, + bottom_border, orig_w, orig_h); while(obj){ if(obj->flags&OSDFLAG_VISIBLE){ vo_osd_changed_flag=obj->flags&OSDFLAG_CHANGED; // temp hack switch(obj->type){ case OSDTYPE_SPU: - vo_draw_spudec_sub(obj, draw_alpha); // FIXME + vo_draw_spudec_sub(obj, draw_alpha, ctx); // FIXME break; #ifdef CONFIG_DVDNAV case OSDTYPE_DVDNAV: @@ -1279,7 +1301,7 @@ void vo_draw_text_ext(int dxs, int dys, int left_border, int top_border, case OSDTYPE_OSD: case OSDTYPE_SUBTITLE: case OSDTYPE_PROGBAR: - vo_draw_text_from_buffer(obj,draw_alpha); + vo_draw_text_from_buffer(obj, draw_alpha, ctx); break; } obj->old_bbox=obj->bbox; @@ -1290,8 +1312,13 @@ void vo_draw_text_ext(int dxs, int dys, int left_border, int top_border, } } -void vo_draw_text(int dxs, int dys, void (*draw_alpha)(int x0, int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride)) { - vo_draw_text_ext(dxs, dys, 0, 0, 0, 0, dxs, dys, draw_alpha); +void osd_draw_text(struct osd_state *osd, int dxs, int dys, + void (*draw_alpha)(void *ctx, int x0, int y0, int w, int h, + unsigned char* src, unsigned char *srca, + int stride), + void *ctx) +{ + osd_draw_text_ext(osd, dxs, dys, 0, 0, 0, 0, dxs, dys, draw_alpha, ctx); } static int vo_osd_changed_status = 0; diff --git a/libvo/sub.h b/libvo/sub.h index 978b4c940d..d5a30e0b86 100644 --- a/libvo/sub.h +++ b/libvo/sub.h @@ -66,14 +66,16 @@ typedef struct mp_osd_obj_s { unsigned char *bitmap_buffer; } mp_osd_obj_t; +struct osd_state { + unsigned char osd_text[128]; + struct font_desc *sub_font; +}; #include "subreader.h" extern sub_data* subdata; //currently used subtitles extern subtitle* vo_sub; -extern unsigned char* vo_osd_text; - extern void* vo_osd_teletext_page; extern int vo_osd_teletext_half; extern int vo_osd_teletext_mode; @@ -105,8 +107,8 @@ extern void* vo_vobsub; #define OSD_PB_1 0x13 /* now in textform */ -extern char * sub_osd_names[]; -extern char * sub_osd_names_short[]; +extern char * const sub_osd_names[]; +extern char * const sub_osd_names_short[]; extern int sub_unicode; extern int sub_utf8; @@ -122,17 +124,27 @@ extern int spu_alignment; extern int spu_aamode; extern float spu_gaussvar; -void vo_draw_text(int dxs,int dys,void (*draw_alpha)(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride)); -void vo_draw_text_ext(int dxs, int dys, int left_border, int top_border, - int right_border, int bottom_border, int orig_w, int orig_h, - void (*draw_alpha)(int x0, int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride)); -void vo_remove_text(int dxs,int dys,void (*remove)(int x0,int y0, int w,int h)); - -void vo_init_osd(void); -int vo_update_osd(int dxs,int dys); +void osd_draw_text(struct osd_state *osd, int dxs, int dys, + void (*draw_alpha)(void *ctx, int x0, int y0, int w, int h, + unsigned char* src, unsigned char *srca, + int stride), + void *ctx); +void osd_draw_text_ext(struct osd_state *osd, int dxs, int dys, + int left_border, int top_border, int right_border, + int bottom_border, int orig_w, int orig_h, + void (*draw_alpha)(void *ctx, int x0, int y0, int w, + int h, unsigned char* src, + unsigned char *srca, + int stride), + void *ctx); +void osd_remove_text(struct osd_state *osd, int dxs, int dys, + void (*remove)(int x0, int y0, int w, int h)); + +struct osd_state *osd_create(void); +int osd_update(struct osd_state *osd, int dxs, int dys); int vo_osd_changed(int new_value); int vo_osd_check_range_update(int,int,int,int); -void free_osd_list(void); +void osd_free(struct osd_state *osd); extern int vo_osd_changed_flag; @@ -143,4 +155,9 @@ unsigned utf8_get_char(const char **str); void osd_set_nav_box (uint16_t sx, uint16_t sy, uint16_t ex, uint16_t ey); #endif + +#ifdef IS_OLD_VO +#define vo_remove_text(...) osd_remove_text(global_osd, __VA_ARGS__) +#endif + #endif /* MPLAYER_SUB_H */ diff --git a/libvo/vesa_lvo.c b/libvo/vesa_lvo.c index 53779a1c13..8875c3aa80 100644 --- a/libvo/vesa_lvo.c +++ b/libvo/vesa_lvo.c @@ -54,13 +54,13 @@ static uint8_t *lvo_mem = NULL; static uint8_t next_frame; static mga_vid_config_t mga_vid_config; static unsigned image_bpp,image_height,image_width,src_format; -uint32_t vlvo_control(uint32_t request, void *data, ...); +int vlvo_control(uint32_t request, void *data); #define PIXEL_SIZE() ((video_mode_info.BitsPerPixel+7)/8) #define SCREEN_LINE_SIZE(pixel_size) (video_mode_info.XResolution*(pixel_size) ) #define IMAGE_LINE_SIZE(pixel_size) (image_width*(pixel_size)) -extern vo_functions_t video_out_vesa; +extern struct vo_old_functions video_out_vesa; int vlvo_preinit(const char *drvname) { @@ -166,7 +166,7 @@ void vlvo_term( void ) if(lvo_handler != -1) close(lvo_handler); } -uint32_t vlvo_draw_slice_420(uint8_t *image[], int stride[], int w,int h,int x,int y) +int vlvo_draw_slice_420(uint8_t *image[], int stride[], int w,int h,int x,int y) { uint8_t *src; uint8_t *dest; @@ -206,7 +206,7 @@ uint32_t vlvo_draw_slice_420(uint8_t *image[], int stride[], int w,int h,int x,i return 0; } -uint32_t vlvo_draw_slice(uint8_t *image[], int stride[], int w,int h,int x,int y) +int vlvo_draw_slice(uint8_t *image[], int stride[], int w,int h,int x,int y) { if( mp_msg_test(MSGT_VO,MSGL_DBG2) ) { mp_msg(MSGT_VO,MSGL_DBG2, "vesa_lvo: vlvo_draw_slice() was called\n");} @@ -224,7 +224,7 @@ uint32_t vlvo_draw_slice(uint8_t *image[], int stride[], int w,int h,int x,int y return 0; } -uint32_t vlvo_draw_frame(uint8_t *image[]) +int vlvo_draw_frame(uint8_t *image[]) { /* Note it's very strange but sometime for YUY2 draw_frame is called */ fast_memcpy(lvo_mem,image[0],mga_vid_config.frame_size); @@ -314,7 +314,7 @@ uint32_t vlvo_query_info(uint32_t format) return VFCAP_CSP_SUPPORTED; } -uint32_t vlvo_control(uint32_t request, void *data, ...) +int vlvo_control(uint32_t request, void *data) { switch (request) { case VOCTRL_QUERY_FORMAT: diff --git a/libvo/vesa_lvo.h b/libvo/vesa_lvo.h index 1e7887c8ae..9d77f60045 100644 --- a/libvo/vesa_lvo.h +++ b/libvo/vesa_lvo.h @@ -32,8 +32,8 @@ int vlvo_init(unsigned src_width,unsigned src_height, void vlvo_term( void ); uint32_t vlvo_query_info(uint32_t format); -uint32_t vlvo_draw_slice(uint8_t *image[], int stride[], int w,int h,int x,int y); -uint32_t vlvo_draw_frame(uint8_t *src[]); +int vlvo_draw_slice(uint8_t *image[], int stride[], int w,int h,int x,int y); +int vlvo_draw_frame(uint8_t *src[]); void vlvo_flip_page(void); void vlvo_draw_osd(void); diff --git a/libvo/video_out.c b/libvo/video_out.c index 27853d5ed4..6d177ecabe 100644 --- a/libvo/video_out.c +++ b/libvo/video_out.c @@ -26,6 +26,8 @@ //#include <sys/mman.h> #include "config.h" +#include "options.h" +#include "talloc.h" #include "video_out.h" #include "aspect.h" #include "geometry.h" @@ -34,27 +36,14 @@ #include "help_mp.h" #include "osdep/shmem.h" - -//int vo_flags=0; +#ifdef CONFIG_X11 +#include "x11_common.h" +#endif int xinerama_screen = -1; int xinerama_x; int xinerama_y; -// currect resolution/bpp on screen: (should be autodetected by vo_init()) -int vo_depthonscreen=0; -int vo_screenwidth=0; -int vo_screenheight=0; - -int vo_config_count=0; - -// requested resolution/bpp: (-x -y -bpp options) -int vo_dx=0; -int vo_dy=0; -int vo_dwidth=0; -int vo_dheight=0; -int vo_dbpp=0; - int vo_nomouse_input = 0; int vo_grabpointer = 1; int vo_doublebuffering = 1; @@ -62,7 +51,6 @@ int vo_vsync = 0; int vo_fs = 0; int vo_fsmode = 0; float vo_panscan = 0.0f; -int vo_ontop = 0; int vo_adapter_num=0; int vo_refresh_rate=0; int vo_keepaspect=1; @@ -82,56 +70,56 @@ int vo_colorkey = 0x0000ff00; // default colorkey is green // // Externally visible list of all vo drivers // -extern vo_functions_t video_out_mga; -extern vo_functions_t video_out_xmga; -extern vo_functions_t video_out_x11; -extern vo_functions_t video_out_xover; -extern vo_functions_t video_out_xvmc; -extern vo_functions_t video_out_xv; -extern vo_functions_t video_out_gl; -extern vo_functions_t video_out_gl2; -extern vo_functions_t video_out_dga; -extern vo_functions_t video_out_sdl; -extern vo_functions_t video_out_3dfx; -extern vo_functions_t video_out_tdfxfb; -extern vo_functions_t video_out_s3fb; -extern vo_functions_t video_out_wii; -extern vo_functions_t video_out_null; -extern vo_functions_t video_out_zr; -extern vo_functions_t video_out_zr2; -extern vo_functions_t video_out_bl; -extern vo_functions_t video_out_fbdev; -extern vo_functions_t video_out_fbdev2; -extern vo_functions_t video_out_svga; -extern vo_functions_t video_out_png; -extern vo_functions_t video_out_ggi; -extern vo_functions_t video_out_aa; -extern vo_functions_t video_out_caca; -extern vo_functions_t video_out_mpegpes; -extern vo_functions_t video_out_yuv4mpeg; -extern vo_functions_t video_out_direct3d; -extern vo_functions_t video_out_directx; -extern vo_functions_t video_out_dxr2; -extern vo_functions_t video_out_dxr3; -extern vo_functions_t video_out_ivtv; -extern vo_functions_t video_out_v4l2; -extern vo_functions_t video_out_jpeg; -extern vo_functions_t video_out_gif89a; -extern vo_functions_t video_out_vesa; -extern vo_functions_t video_out_directfb; -extern vo_functions_t video_out_dfbmga; -extern vo_functions_t video_out_xvidix; -extern vo_functions_t video_out_winvidix; -extern vo_functions_t video_out_cvidix; -extern vo_functions_t video_out_tdfx_vid; -extern vo_functions_t video_out_xvr100; -extern vo_functions_t video_out_tga; -extern vo_functions_t video_out_macosx; -extern vo_functions_t video_out_quartz; -extern vo_functions_t video_out_pnm; -extern vo_functions_t video_out_md5sum; - -const vo_functions_t* const video_out_drivers[] = +extern struct vo_driver video_out_mga; +extern struct vo_driver video_out_xmga; +extern struct vo_driver video_out_x11; +extern struct vo_driver video_out_xover; +extern struct vo_driver video_out_xvmc; +extern struct vo_driver video_out_xv; +extern struct vo_driver video_out_gl; +extern struct vo_driver video_out_gl2; +extern struct vo_driver video_out_dga; +extern struct vo_driver video_out_sdl; +extern struct vo_driver video_out_3dfx; +extern struct vo_driver video_out_tdfxfb; +extern struct vo_driver video_out_s3fb; +extern struct vo_driver video_out_wii; +extern struct vo_driver video_out_null; +extern struct vo_driver video_out_zr; +extern struct vo_driver video_out_zr2; +extern struct vo_driver video_out_bl; +extern struct vo_driver video_out_fbdev; +extern struct vo_driver video_out_fbdev2; +extern struct vo_driver video_out_svga; +extern struct vo_driver video_out_png; +extern struct vo_driver video_out_ggi; +extern struct vo_driver video_out_aa; +extern struct vo_driver video_out_caca; +extern struct vo_driver video_out_mpegpes; +extern struct vo_driver video_out_yuv4mpeg; +extern struct vo_driver video_out_direct3d; +extern struct vo_driver video_out_directx; +extern struct vo_driver video_out_dxr2; +extern struct vo_driver video_out_dxr3; +extern struct vo_driver video_out_ivtv; +extern struct vo_driver video_out_v4l2; +extern struct vo_driver video_out_jpeg; +extern struct vo_driver video_out_gif89a; +extern struct vo_driver video_out_vesa; +extern struct vo_driver video_out_directfb; +extern struct vo_driver video_out_dfbmga; +extern struct vo_driver video_out_xvidix; +extern struct vo_driver video_out_winvidix; +extern struct vo_driver video_out_cvidix; +extern struct vo_driver video_out_tdfx_vid; +extern struct vo_driver video_out_xvr100; +extern struct vo_driver video_out_tga; +extern struct vo_driver video_out_macosx; +extern struct vo_driver video_out_quartz; +extern struct vo_driver video_out_pnm; +extern struct vo_driver video_out_md5sum; + +const struct vo_driver *video_out_drivers[] = { #ifdef CONFIG_XVR100 &video_out_xvr100, @@ -269,79 +257,152 @@ const vo_functions_t* const video_out_drivers[] = NULL }; -void list_video_out(void){ - int i=0; - mp_msg(MSGT_CPLAYER, MSGL_INFO, MSGTR_AvailableVideoOutputDrivers); - mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_VIDEO_OUTPUTS\n"); - while (video_out_drivers[i]) { + +static int vo_preinit(struct vo *vo, const char *arg) +{ + return vo->driver->preinit(vo, arg); +} + +int vo_control(struct vo *vo, uint32_t request, void *data) +{ + return vo->driver->control(vo, request, data); +} + +int vo_draw_frame(struct vo *vo, uint8_t *src[]) +{ + if (!vo->config_ok) + return 0; + return vo->driver->draw_frame(vo, src); +} + +int vo_draw_slice(struct vo *vo, uint8_t *src[], int stride[], int w, int h, int x, int y) +{ + return vo->driver->draw_slice(vo, src, stride, w, h, x, y); +} + +void vo_draw_osd(struct vo *vo, struct osd_state *osd) +{ + if (!vo->config_ok) + return; + vo->driver->draw_osd(vo, osd); +} + +void vo_flip_page(struct vo *vo) +{ + if (!vo->config_ok) + return; + vo->driver->flip_page(vo); +} + +void vo_check_events(struct vo *vo) +{ + if (!vo->config_ok) + return; + vo->driver->check_events(vo); +} + +void vo_destroy(struct vo *vo) +{ + vo->driver->uninit(vo); + talloc_free(vo); +} + +void list_video_out(void) +{ + int i = 0; + mp_msg(MSGT_CPLAYER, MSGL_INFO, MSGTR_AvailableVideoOutputDrivers); + mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_VIDEO_OUTPUTS\n"); + while (video_out_drivers[i]) { const vo_info_t *info = video_out_drivers[i++]->info; mp_msg(MSGT_GLOBAL, MSGL_INFO,"\t%s\t%s\n", info->short_name, info->name); - } - mp_msg(MSGT_GLOBAL, MSGL_INFO,"\n"); + } + mp_msg(MSGT_GLOBAL, MSGL_INFO,"\n"); } -const vo_functions_t* init_best_video_out(char** vo_list){ +struct vo *init_best_video_out(struct MPOpts *opts, struct vo_x11_state *x11, + struct mp_fifo *key_fifo, + struct input_ctx *input_ctx) +{ + char **vo_list = opts->video_driver_list; int i; + struct vo *vo = talloc_ptrtype(NULL, vo); + struct vo initial_values = { + .opts = opts, + .x11 = x11, + .key_fifo = key_fifo, + .input_ctx = input_ctx, + }; // first try the preferred drivers, with their optional subdevice param: - if(vo_list && vo_list[0]) - while(vo_list[0][0]){ - char* vo=strdup(vo_list[0]); - vo_subdevice=strchr(vo,':'); - if (!strcmp(vo, "pgm")) - mp_msg(MSGT_CPLAYER, MSGL_ERR, MSGTR_VO_PGM_HasBeenReplaced); - if (!strcmp(vo, "md5")) - mp_msg(MSGT_CPLAYER, MSGL_ERR, MSGTR_VO_MD5_HasBeenReplaced); - if(vo_subdevice){ - vo_subdevice[0]=0; - ++vo_subdevice; - } - for(i=0;video_out_drivers[i];i++){ - const vo_functions_t* video_driver=video_out_drivers[i]; - const vo_info_t *info = video_driver->info; - if(!strcmp(info->short_name,vo)){ - // name matches, try it - if(!video_driver->preinit(vo_subdevice)) - { - free(vo); - return video_driver; // success! + if (vo_list && vo_list[0]) + while (vo_list[0][0]) { + char *name = strdup(vo_list[0]); + vo_subdevice = strchr(name,':'); + if (!strcmp(name, "pgm")) + mp_msg(MSGT_CPLAYER, MSGL_ERR, MSGTR_VO_PGM_HasBeenReplaced); + if (!strcmp(name, "md5")) + mp_msg(MSGT_CPLAYER, MSGL_ERR, MSGTR_VO_MD5_HasBeenReplaced); + if (vo_subdevice) { + vo_subdevice[0] = 0; + ++vo_subdevice; + } + for (i = 0; video_out_drivers[i]; i++) { + const struct vo_driver *video_driver = video_out_drivers[i]; + const vo_info_t *info = video_driver->info; + if (!strcmp(info->short_name, name)) { + // name matches, try it + *vo = initial_values; + vo->driver = video_driver; + if (!vo_preinit(vo, vo_subdevice)) { + free(name); + return vo; // success! + } } } + // continue... + free(name); + ++vo_list; + if (!(vo_list[0])) + return NULL; // do NOT fallback to others } - // continue... - free(vo); - ++vo_list; - if(!(vo_list[0])) return NULL; // do NOT fallback to others - } // now try the rest... - vo_subdevice=NULL; - for(i=0;video_out_drivers[i];i++){ - const vo_functions_t* video_driver=video_out_drivers[i]; - if(!video_driver->preinit(vo_subdevice)) - return video_driver; // success! + vo_subdevice = NULL; + for (i = 0; video_out_drivers[i]; i++) { + const struct vo_driver *video_driver = video_out_drivers[i]; + *vo = initial_values; + vo->driver = video_driver; + if (!vo_preinit(vo, vo_subdevice)) + return vo; // success! } + free(vo); return NULL; } -int config_video_out(const vo_functions_t *vo, uint32_t width, uint32_t height, +int vo_config(struct vo *vo, uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uint32_t flags, - char *title, uint32_t format) { - panscan_init(); - aspect_save_orig(width,height); - aspect_save_prescale(d_width,d_height); - - if (vo->control(VOCTRL_UPDATE_SCREENINFO, NULL) == VO_TRUE) { - aspect(&d_width,&d_height,A_NOZOOM); - vo_dx = (int)(vo_screenwidth - d_width) / 2; - vo_dy = (int)(vo_screenheight - d_height) / 2; - geometry(&vo_dx, &vo_dy, &d_width, &d_height, - vo_screenwidth, vo_screenheight); - vo_dx += xinerama_x; - vo_dy += xinerama_y; - vo_dwidth = d_width; - vo_dheight = d_height; - } + char *title, uint32_t format) +{ + struct MPOpts *opts = vo->opts; + panscan_init(vo); + aspect_save_orig(vo, width, height); + aspect_save_prescale(vo, d_width, d_height); + + if (vo_control(vo, VOCTRL_UPDATE_SCREENINFO, NULL) == VO_TRUE) { + aspect(vo, &d_width, &d_height, A_NOZOOM); + vo->dx = (int)(opts->vo_screenwidth - d_width) / 2; + vo->dy = (int)(opts->vo_screenheight - d_height) / 2; + geometry(&vo->dx, &vo->dy, &d_width, &d_height, + opts->vo_screenwidth, opts->vo_screenheight); + vo->dx += xinerama_x; + vo->dy += xinerama_y; + vo->dwidth = d_width; + vo->dheight = d_height; + } - return vo->config(width, height, d_width, d_height, flags, title, format); + int ret = vo->driver->config(vo, width, height, d_width, d_height, flags, + title, format); + vo->config_ok = (ret == 0); + vo->config_count += vo->config_ok; + return ret; } /** @@ -384,7 +445,7 @@ static void src_dst_split_scaling(int src_size, int dst_size, int scaled_src_siz * * \param crop specifies the cropping border size in the left, right, top and bottom members, may be NULL */ -void calc_src_dst_rects(int src_width, int src_height, struct vo_rect *src, struct vo_rect *dst, struct vo_rect *crop) { +void calc_src_dst_rects(struct vo *vo, int src_width, int src_height, struct vo_rect *src, struct vo_rect *dst, struct vo_rect *crop) { static const struct vo_rect no_crop = {0, 0, 0, 0, 0, 0}; int scaled_width = 0; int scaled_height = 0; @@ -393,18 +454,18 @@ void calc_src_dst_rects(int src_width, int src_height, struct vo_rect *src, stru src_height -= crop->top + crop->bottom; if (src_width < 2) src_width = 2; if (src_height < 2) src_height = 2; - dst->left = 0; dst->right = vo_dwidth; - dst->top = 0; dst->bottom = vo_dheight; + dst->left = 0; dst->right = vo->dwidth; + dst->top = 0; dst->bottom = vo->dheight; src->left = 0; src->right = src_width; src->top = 0; src->bottom = src_height; if (vo_fs) { - aspect(&scaled_width, &scaled_height, A_ZOOM); - panscan_calc(); - scaled_width += vo_panscan_x; - scaled_height += vo_panscan_y; - src_dst_split_scaling(src_width, vo_dwidth, scaled_width, + aspect(vo, &scaled_width, &scaled_height, A_ZOOM); + panscan_calc(vo); + scaled_width += vo->panscan_x; + scaled_height += vo->panscan_y; + src_dst_split_scaling(src_width, vo->dwidth, scaled_width, &src->left, &src->right, &dst->left, &dst->right); - src_dst_split_scaling(src_height, vo_dheight, scaled_height, + src_dst_split_scaling(src_height, vo->dheight, scaled_height, &src->top, &src->bottom, &dst->top, &dst->bottom); } src->left += crop->left; src->right += crop->left; diff --git a/libvo/video_out.h b/libvo/video_out.h index bc63712826..64d4e1bb77 100644 --- a/libvo/video_out.h +++ b/libvo/video_out.h @@ -60,7 +60,15 @@ #define VOCTRL_SET_PANSCAN 16 /* equalizer controls */ #define VOCTRL_SET_EQUALIZER 17 +struct voctrl_set_equalizer_args { + const char *name; + int value; +}; #define VOCTRL_GET_EQUALIZER 18 +struct voctrl_get_equalizer_args { + const char *name; + int *valueptr; +}; //#define VOCTRL_GUI_NOWINDOW 19 /* Frame duplication */ #define VOCTRL_DUPLICATE_FRAME 20 @@ -92,6 +100,8 @@ typedef struct { } mp_colorkey_t; #define VOCTRL_XOVERLAY_SET_WIN 23 +#define VOCTRL_REDRAW_OSD 24 + typedef struct { int x,y; int w,h; @@ -121,15 +131,24 @@ typedef struct vo_info_s const char *comment; } vo_info_t; -typedef struct vo_functions_s -{ +struct vo; +struct osd_state; + +struct vo_driver { + // Driver uses new API + int is_new; + + // This is set if the driver is not new and contains pointers to + // old-API functions to be used instead of the ones below. + struct vo_old_functions *old_functions; + const vo_info_t *info; /* * Preinitializes driver (real INITIALIZATION) * arg - currently it's vo_subdevice * returns: zero on successful initialization, non-zero on error. */ - int (*preinit)(const char *arg); + int (*preinit)(struct vo *vo, const char *arg); /* * Initialize (means CONFIGURE) the display driver. * params: @@ -140,21 +159,21 @@ typedef struct vo_functions_s * format: fourcc of pixel format * returns : zero on successful initialization, non-zero on error. */ - int (*config)(uint32_t width, uint32_t height, uint32_t d_width, - uint32_t d_height, uint32_t fullscreen, char *title, - uint32_t format); + int (*config)(struct vo *vo, uint32_t width, uint32_t height, + uint32_t d_width, uint32_t d_height, uint32_t fullscreen, + char *title, uint32_t format); /* * Control interface */ - int (*control)(uint32_t request, void *data, ...); + int (*control)(struct vo *vo, uint32_t request, void *data); /* * Display a new RGB/BGR frame of the video to the screen. * params: * src[0] - pointer to the image */ - int (*draw_frame)(uint8_t *src[]); + int (*draw_frame)(struct vo *vo, uint8_t *src[]); /* * Draw a planar YUV slice to the buffer: @@ -164,60 +183,100 @@ typedef struct vo_functions_s * w,h = width*height of area to be copied (in Y pixels) * x,y = position at the destination image (in Y pixels) */ - int (*draw_slice)(uint8_t *src[], int stride[], int w,int h, int x,int y); + int (*draw_slice)(struct vo *vo, uint8_t *src[], int stride[], int w, + int h, int x, int y); /* * Draws OSD to the screen buffer */ - void (*draw_osd)(void); + void (*draw_osd)(struct vo *vo, struct osd_state *osd); /* * Blit/Flip buffer to the screen. Must be called after each frame! */ - void (*flip_page)(void); + void (*flip_page)(struct vo *vo); /* * This func is called after every frames to handle keyboard and * other events. It's called in PAUSE mode too! */ - void (*check_events)(void); + void (*check_events)(struct vo *vo); /* * Closes driver. Should restore the original state of the system. */ - void (*uninit)(void); + void (*uninit)(struct vo *vo); +}; -} vo_functions_t; +struct vo_old_functions { + int (*preinit)(const char *arg); + int (*config)(uint32_t width, uint32_t height, uint32_t d_width, + uint32_t d_height, uint32_t fullscreen, char *title, + uint32_t format); + int (*control)(uint32_t request, void *data); + int (*draw_frame)(uint8_t *src[]); + int (*draw_slice)(uint8_t *src[], int stride[], int w,int h, int x,int y); + void (*draw_osd)(void); + void (*flip_page)(void); + void (*check_events)(void); + void (*uninit)(void); +}; + +struct vo { + int config_ok; // Last config call was successful? + int config_count; // Total number of successful config calls + const struct vo_driver *driver; + void *priv; + struct MPOpts *opts; + struct vo_x11_state *x11; + struct mp_fifo *key_fifo; + struct input_ctx *input_ctx; + + // requested position/resolution + int dx; + int dy; + int dwidth; + int dheight; + + int panscan_x; + int panscan_y; + float panscan_amount; + float monitor_aspect; + struct aspect_data { + int orgw; // real width + int orgh; // real height + int prew; // prescaled width + int preh; // prescaled height + int scrw; // horizontal resolution + int scrh; // vertical resolution + float asp; + } aspdat; +}; -const vo_functions_t* init_best_video_out(char** vo_list); -int config_video_out(const vo_functions_t *vo, uint32_t width, uint32_t height, +struct vo *init_best_video_out(struct MPOpts *opts, struct vo_x11_state *x11, + struct mp_fifo *key_fifo, + struct input_ctx *input_ctx); +int vo_config(struct vo *vo, uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uint32_t flags, char *title, uint32_t format); void list_video_out(void); -// NULL terminated array of all drivers -extern const vo_functions_t* const video_out_drivers[]; +int vo_control(struct vo *vo, uint32_t request, void *data); +int vo_draw_frame(struct vo *vo, uint8_t *src[]); +int vo_draw_slice(struct vo *vo, uint8_t *src[], int stride[], int w, int h, int x, int y); +void vo_draw_osd(struct vo *vo, struct osd_state *osd); +void vo_flip_page(struct vo *vo); +void vo_check_events(struct vo *vo); +void vo_destroy(struct vo *vo); -extern int vo_flags; -extern int vo_config_count; +// NULL terminated array of all drivers +extern const struct vo_driver *video_out_drivers[]; extern int xinerama_screen; extern int xinerama_x; extern int xinerama_y; -// correct resolution/bpp on screen: (should be autodetected by vo_init()) -extern int vo_depthonscreen; -extern int vo_screenwidth; -extern int vo_screenheight; - -// requested resolution/bpp: (-x -y -bpp options) -extern int vo_dx; -extern int vo_dy; -extern int vo_dwidth; -extern int vo_dheight; -extern int vo_dbpp; - extern int vo_grabpointer; extern int vo_doublebuffering; extern int vo_directrendering; @@ -229,18 +288,8 @@ extern int vo_adapter_num; extern int vo_refresh_rate; extern int vo_keepaspect; extern int vo_rootwin; -extern int vo_ontop; extern int vo_border; -extern int vo_gamma_gamma; -extern int vo_gamma_brightness; -extern int vo_gamma_saturation; -extern int vo_gamma_contrast; -extern int vo_gamma_hue; -extern int vo_gamma_red_intensity; -extern int vo_gamma_green_intensity; -extern int vo_gamma_blue_intensity; - extern int vo_nomouse_input; extern int vo_pts; @@ -272,6 +321,6 @@ int lookup_keymap_table(const struct keymap *map, int key); struct vo_rect { int left, right, top, bottom, width, height; }; -void calc_src_dst_rects(int src_width, int src_height, struct vo_rect *src, struct vo_rect *dst, struct vo_rect *crop); +void calc_src_dst_rects(struct vo *vo, int src_width, int src_height, struct vo_rect *src, struct vo_rect *dst, struct vo_rect *crop); #endif /* MPLAYER_VIDEO_OUT_H */ diff --git a/libvo/video_out_internal.h b/libvo/video_out_internal.h index 36aa210fdd..166a91cc1c 100644 --- a/libvo/video_out_internal.h +++ b/libvo/video_out_internal.h @@ -27,8 +27,10 @@ #include "libmpcodecs/vfcap.h" #include "libmpcodecs/mp_image.h" #include "geometry.h" +#include "old_vo_wrapper.h" +#include "old_vo_defines.h" -static int control(uint32_t request, void *data, ...); +static int control(uint32_t request, void *data); static int config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uint32_t fullscreen, char *title, uint32_t format); @@ -41,9 +43,20 @@ static void uninit(void); static int query_format(uint32_t format); static int preinit(const char *); -#define LIBVO_EXTERN(x) vo_functions_t video_out_##x =\ +#define LIBVO_EXTERN(x) struct vo_driver video_out_##x =\ {\ - &info,\ + .is_new = 0,\ + .info = &info,\ + .preinit = old_vo_preinit,\ + .config = old_vo_config,\ + .control = old_vo_control,\ + .draw_frame = old_vo_draw_frame,\ + .draw_slice = old_vo_draw_slice,\ + .draw_osd = old_vo_draw_osd,\ + .flip_page = old_vo_flip_page,\ + .check_events = old_vo_check_events,\ + .uninit = old_vo_uninit,\ + .old_functions = &(struct vo_old_functions){\ preinit,\ config,\ control,\ @@ -52,7 +65,8 @@ static int preinit(const char *); draw_osd,\ flip_page,\ check_events,\ - uninit\ + uninit,\ + }\ }; #include "osd.h" diff --git a/libvo/vo_3dfx.c b/libvo/vo_3dfx.c index 93776d4318..da52a57a01 100644 --- a/libvo/vo_3dfx.c +++ b/libvo/vo_3dfx.c @@ -497,7 +497,7 @@ static int preinit(const char *arg) return 0; } -static int control(uint32_t request, void *data, ...) +static int control(uint32_t request, void *data) { switch (request) { case VOCTRL_QUERY_FORMAT: diff --git a/libvo/vo_aa.c b/libvo/vo_aa.c index 5046a8b9ec..d0807dc132 100644 --- a/libvo/vo_aa.c +++ b/libvo/vo_aa.c @@ -96,7 +96,9 @@ static struct SwsContext *sws=NULL; int aaopt_osdcolor = AA_SPECIAL; int aaopt_subcolor = AA_SPECIAL; -void +static unsigned char vo_osd_text[64]; + +static void resize(void){ /* * this function is called by aa lib if windows resizes @@ -192,15 +194,10 @@ osdpercent(int duration, int deko, int min, int max, int val, const char * desc, static void printosdtext(void) { - if(osd_text_length > 0 && !vo_osd_text) { - memset(c->textbuffer,' ',osd_text_length); - memset(c->attrbuffer,0,osd_text_length); - osd_text_length = 0; - } /* * places the mplayer status osd */ - if (vo_osd_text && vo_osd_text[0] != 0) { + if (vo_osd_text[0] != 0) { int len; if(vo_osd_text[0] < 32) { len = strlen(sub_osd_names_short[vo_osd_text[0]]) + strlen(vo_osd_text+1) + 2; @@ -544,18 +541,18 @@ static void clear_alpha(int x0,int y0, int w,int h) { static void draw_osd(void){ - char * vo_osd_text_save; + char vo_osd_text_save; int vo_osd_progbar_type_save; printosdprogbar(); /* let vo_draw_text only write subtitle */ - vo_osd_text_save=vo_osd_text; /* we have to save the osd_text */ - vo_osd_text=NULL; + vo_osd_text_save = global_osd->osd_text[0]; + global_osd->osd_text[0] = 0; vo_osd_progbar_type_save=vo_osd_progbar_type; vo_osd_progbar_type=-1; vo_remove_text(aa_scrwidth(c), aa_scrheight(c),clear_alpha); vo_draw_text(aa_scrwidth(c), aa_scrheight(c), draw_alpha); - vo_osd_text=vo_osd_text_save; + global_osd->osd_text[0] = vo_osd_text_save; vo_osd_progbar_type=vo_osd_progbar_type_save; } @@ -728,37 +725,26 @@ static int preinit(const char *arg) return 0; } -static int control(uint32_t request, void *data, ...) +static int control(uint32_t request, void *data) { switch (request) { case VOCTRL_QUERY_FORMAT: return query_format(*((uint32_t*)data)); case VOCTRL_SET_EQUALIZER: { - va_list ap; - int val; - - va_start(ap, data); - val = va_arg(ap, int); - va_end(ap); - - if(strcmp((char*)data,"contrast") == 0) - p->contrast = ( val + 100 ) * 64 / 100; - else if(strcmp((char*)data,"brightness") == 0) - p->bright = ( val + 100) * 128 / 100; + struct voctrl_set_equalizer_args *args = data; + if (strcmp(args->name, "contrast") == 0) + p->contrast = (args->value + 100) * 64 / 100; + else if (strcmp(args->name, "brightness") == 0) + p->bright = (args->value + 100) * 128 / 100; return VO_TRUE; } case VOCTRL_GET_EQUALIZER: { - va_list ap; - int* val; - - va_start(ap, data); - val = va_arg(ap, int*); - va_end(ap); + struct voctrl_get_equalizer_args *args = data; - if(strcmp((char*)data,"contrast") == 0) - *val = (p->contrast - 64) * 100 / 64; - else if(strcmp((char*)data,"brightness") == 0) - *val = (p->bright - 128) * 100 / 128; + if (strcmp(args->name, "contrast") == 0) + *args->valueptr = (p->contrast - 64) * 100 / 64; + else if (strcmp(args->name, "brightness") == 0) + *args->valueptr = (p->bright - 128) * 100 / 128; return VO_TRUE; } diff --git a/libvo/vo_bl.c b/libvo/vo_bl.c index a194ade17a..548e8c7f4f 100644 --- a/libvo/vo_bl.c +++ b/libvo/vo_bl.c @@ -469,7 +469,7 @@ static int preinit(const char *arg) { return 0; } -static int control(uint32_t request, void *data, ...) { +static int control(uint32_t request, void *data) { switch (request) { case VOCTRL_QUERY_FORMAT: return query_format(*((uint32_t*)data)); diff --git a/libvo/vo_caca.c b/libvo/vo_caca.c index 36ceb03762..c9bdd19568 100644 --- a/libvo/vo_caca.c +++ b/libvo/vo_caca.c @@ -335,7 +335,7 @@ static int query_format(uint32_t format) return 0; } -static int control(uint32_t request, void *data, ...) +static int control(uint32_t request, void *data) { switch(request) { diff --git a/libvo/vo_cvidix.c b/libvo/vo_cvidix.c index 68c779a2c0..9fa24fa7c4 100644 --- a/libvo/vo_cvidix.c +++ b/libvo/vo_cvidix.c @@ -171,11 +171,11 @@ static int preinit(const char *arg){ mp_msg(MSGT_VO, MSGL_INFO, "vo_cvidix: No vidix driver name provided, probing available ones (-v option for details)!\n"); vidix_name = NULL; } - if(vidix_preinit(vidix_name, &video_out_cvidix))return 1; + if (vidix_preinit(vidix_name, video_out_cvidix.old_functions))return 1; return 0; } -static int control(uint32_t request, void *data, ...){ +static int control(uint32_t request, void *data){ switch (request) { case VOCTRL_QUERY_FORMAT: return query_format(*((uint32_t*)data)); @@ -184,24 +184,6 @@ static int control(uint32_t request, void *data, ...){ else vo_fs=1; setup_vidix(); return VO_TRUE; - case VOCTRL_SET_EQUALIZER: - { - va_list ap; - int value; - va_start(ap, data); - value = va_arg(ap, int); - va_end(ap); - return vidix_control(request, data, value); - } - case VOCTRL_GET_EQUALIZER: - { - va_list ap; - int *value; - va_start(ap, data); - value = va_arg(ap, int *); - va_end(ap); - return vidix_control(request, data, value); - } } return vidix_control(request, data); } diff --git a/libvo/vo_dfbmga.c b/libvo/vo_dfbmga.c index fd1a3638db..73d67c4f8e 100644 --- a/libvo/vo_dfbmga.c +++ b/libvo/vo_dfbmga.c @@ -1465,7 +1465,7 @@ get_equalizer( char *data, int *value ) } static int -control( uint32_t request, void *data, ... ) +control( uint32_t request, void *data) { switch (request) { case VOCTRL_GUISUPPORT: @@ -1483,25 +1483,13 @@ control( uint32_t request, void *data, ... ) case VOCTRL_SET_EQUALIZER: { - va_list ap; - int value; - - va_start( ap, data ); - value = va_arg( ap, int ); - va_end( ap ); - - return set_equalizer( data, value ); + struct voctrl_set_equalizer_args *args = data; + return set_equalizer(args->name, args->value); } case VOCTRL_GET_EQUALIZER: { - va_list ap; - int *value; - - va_start( ap, data ); - value = va_arg( ap, int* ); - va_end( ap ); - - return get_equalizer( data, value ); + struct voctrl_get_equalizer_args *args = data; + return get_equalizer(args->name, args->valueptr); } } diff --git a/libvo/vo_dga.c b/libvo/vo_dga.c index a3f2901eb3..3383a30df5 100644 --- a/libvo/vo_dga.c +++ b/libvo/vo_dga.c @@ -984,7 +984,7 @@ static uint32_t get_image(mp_image_t * mpi) return VO_FALSE; } -static int control(uint32_t request, void *data, ...) +static int control(uint32_t request, void *data) { switch (request) { diff --git a/libvo/vo_direct3d.c b/libvo/vo_direct3d.c index c2955f2d44..ef1d0ba9dc 100644 --- a/libvo/vo_direct3d.c +++ b/libvo/vo_direct3d.c @@ -735,7 +735,7 @@ static int preinit(const char *arg) /** @brief libvo Callback: Handle control requests. * @return VO_TRUE on success, VO_NOTIMPL when not implemented */ -static int control(uint32_t request, void *data, ...) +static int control(uint32_t request, void *data) { switch (request) { case VOCTRL_QUERY_FORMAT: diff --git a/libvo/vo_directfb2.c b/libvo/vo_directfb2.c index 133f46a07e..9124ad5dd0 100644 --- a/libvo/vo_directfb2.c +++ b/libvo/vo_directfb2.c @@ -1412,7 +1412,7 @@ static uint32_t put_image(mp_image_t *mpi){ -static int control(uint32_t request, void *data, ...) +static int control(uint32_t request, void *data) { switch (request) { case VOCTRL_QUERY_FORMAT: @@ -1423,25 +1423,13 @@ static int control(uint32_t request, void *data, ...) return put_image(data); case VOCTRL_SET_EQUALIZER: { - va_list ap; - int value; - - va_start(ap, data); - value = va_arg(ap, int); - va_end(ap); - - return directfb_set_video_eq(data, value); + struct voctrl_set_equalizer_args *args = data; + return directfb_set_video_eq(args->name, args->value); } case VOCTRL_GET_EQUALIZER: { - va_list ap; - int *value; - - va_start(ap, data); - value = va_arg(ap, int*); - va_end(ap); - - return directfb_get_video_eq(data, value); + struct voctrl_get_equalizer_args *args = data; + return directfb_get_video_eq(args->name, args->valueptr); } }; return VO_NOTIMPL; diff --git a/libvo/vo_directx.c b/libvo/vo_directx.c index 224af242c2..7d4feaa5e5 100644 --- a/libvo/vo_directx.c +++ b/libvo/vo_directx.c @@ -90,8 +90,6 @@ static float window_aspect; static BOOL (WINAPI* myGetMonitorInfo)(HMONITOR, LPMONITORINFO) = NULL; static RECT last_rect = {0xDEADC0DE, 0xDEADC0DE, 0xDEADC0DE, 0xDEADC0DE}; -extern int vidmode; - /***************************************************************************** * DirectDraw GUIDs. * Defining them here allows us to get rid of the dxguid library during @@ -1474,7 +1472,7 @@ static uint32_t color_ctrl_get(char *what, int *value) return r; } -static int control(uint32_t request, void *data, ...) +static int control(uint32_t request, void *data) { switch (request) { @@ -1566,22 +1564,12 @@ static int control(uint32_t request, void *data, ...) return VO_TRUE; } case VOCTRL_SET_EQUALIZER: { - va_list ap; - int value; - - va_start(ap, data); - value = va_arg(ap, int); - va_end(ap); - return color_ctrl_set(data, value); + struct voctrl_set_equalizer_args *args = data; + return color_ctrl_set(args->name, args->value); } case VOCTRL_GET_EQUALIZER: { - va_list ap; - int *value; - - va_start(ap, data); - value = va_arg(ap, int*); - va_end(ap); - return color_ctrl_get(data, value); + struct voctrl_get_equalizer_args *args = data; + return color_ctrl_get(args->name, args->valueptr); } case VOCTRL_UPDATE_SCREENINFO: if (vidmode) { diff --git a/libvo/vo_dxr2.c b/libvo/vo_dxr2.c index 0bf64f58d6..ccbef40b61 100644 --- a/libvo/vo_dxr2.c +++ b/libvo/vo_dxr2.c @@ -42,8 +42,7 @@ #include <dxr2ioctl.h> -extern float monitor_aspect; -extern float movie_aspect; +#include "aspect.h" int dxr2_fd = -1; @@ -51,7 +50,8 @@ static int movie_w,movie_h; static int playing = 0; // vo device used to blank the screen for the overlay init -static const vo_functions_t* sub_vo = NULL; +static const struct vo_old_functions *sub_vo = NULL; +static const struct vo_info_s *sub_info; static uint8_t* sub_img = NULL; static int sub_x,sub_y,sub_w,sub_h; @@ -446,7 +446,7 @@ static int dxr2_load_vga_params(dxr2_vgaParams_t* vga,char* name) { } static int dxr2_setup_vga_params(void) { - const vo_info_t* vi = sub_vo->info; + const vo_info_t* vi = sub_info; dxr2_vgaParams_t vga; int loaded = dxr2_load_vga_params(&vga,(char*)vi->short_name); @@ -660,7 +660,7 @@ static int config(uint32_t s_width, uint32_t s_height, uint32_t width, uint32_t } // Does the sub vo support the x11 stuff // Fix me : test the other x11 vo's and enable them - if(strcmp(sub_vo->info->short_name,"x11") == 0) + if(strcmp(sub_info->short_name,"x11") == 0) sub_vo_win = 1; else sub_vo_win = 0; @@ -834,10 +834,11 @@ static int preinit(const char *arg) { const vo_info_t* vi = video_out_drivers[n]->info; if(!vi) continue; - if(strcasecmp(arg,vi->short_name) == 0) + if(!video_out_drivers[n]->is_new && strcasecmp(arg,vi->short_name) == 0) break; } - sub_vo = video_out_drivers[n]; + sub_vo = video_out_drivers[n]->old_functions; + sub_info = video_out_drivers[n]->info; } else { mp_msg(MSGT_VO,MSGL_WARN,"VO: [dxr2] We need a sub driver to initialize the overlay\n"); use_ol = 0; @@ -920,7 +921,7 @@ static int preinit(const char *arg) { return 0; } -static int control(uint32_t request, void *data, ...) +static int control(uint32_t request, void *data) { switch (request) { case VOCTRL_QUERY_FORMAT: diff --git a/libvo/vo_dxr3.c b/libvo/vo_dxr3.c index 46ab3468ea..74250b382c 100644 --- a/libvo/vo_dxr3.c +++ b/libvo/vo_dxr3.c @@ -177,7 +177,7 @@ static overlay_t *overlay_data; /* Functions for working with the em8300's internal clock */ /* End of internal clock functions */ -static int control(uint32_t request, void *data, ...) +static int control(uint32_t request, void *data) { switch (request) { case VOCTRL_GUISUPPORT: @@ -255,22 +255,17 @@ static int control(uint32_t request, void *data, ...) } case VOCTRL_SET_EQUALIZER: { - va_list ap; - int value; em8300_bcs_t bcs; - - va_start(ap, data); - value = va_arg(ap, int); - va_end(ap); + struct voctrl_set_equalizer_args *args = data; if (ioctl(fd_control, EM8300_IOCTL_GETBCS, &bcs) < 0) return VO_FALSE; - if (!strcasecmp(data, "brightness")) - bcs.brightness = (value+100)*5; - else if (!strcasecmp(data, "contrast")) - bcs.contrast = (value+100)*5; - else if (!strcasecmp(data, "saturation")) - bcs.saturation = (value+100)*5; + if (!strcasecmp(args->name, "brightness")) + bcs.brightness = (args->value+100)*5; + else if (!strcasecmp(args->name, "contrast")) + bcs.contrast = (args->value+100)*5; + else if (!strcasecmp(args->name, "saturation")) + bcs.saturation = (args->value+100)*5; else return VO_FALSE; if (ioctl(fd_control, EM8300_IOCTL_SETBCS, &bcs) < 0) @@ -279,23 +274,18 @@ static int control(uint32_t request, void *data, ...) } case VOCTRL_GET_EQUALIZER: { - va_list ap; - int *value; em8300_bcs_t bcs; + struct voctrl_get_equalizer_args *args = data; - va_start(ap, data); - value = va_arg(ap, int*); - va_end(ap); - if (ioctl(fd_control, EM8300_IOCTL_GETBCS, &bcs) < 0) return VO_FALSE; - if (!strcasecmp(data, "brightness")) - *value = (bcs.brightness/5)-100; - else if (!strcasecmp(data, "contrast")) - *value = (bcs.contrast/5)-100; - else if (!strcasecmp(data, "saturation")) - *value = (bcs.saturation/5)-100; + if (!strcasecmp(args->name, "brightness")) + *args->valueptr = (bcs.brightness/5)-100; + else if (!strcasecmp(args->name, "contrast")) + *args->valueptr = (bcs.contrast/5)-100; + else if (!strcasecmp(args->name, "saturation")) + *args->valueptr = (bcs.saturation/5)-100; else return VO_FALSE; return VO_TRUE; @@ -325,7 +315,6 @@ static int config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_ { int tmp1, tmp2, size; em8300_register_t reg; - extern float monitor_aspect; /* Softzoom turned on, downscale */ /* This activates the subpicture processor, you can safely disable this and still send */ diff --git a/libvo/vo_fbdev.c b/libvo/vo_fbdev.c index 5f621967cf..a5e51c31f0 100644 --- a/libvo/vo_fbdev.c +++ b/libvo/vo_fbdev.c @@ -1085,7 +1085,8 @@ static int preinit(const char *vo_subdevice) if (memcmp(vo_subdevice, "vidix", 5) == 0) vidix_name = &vo_subdevice[5]; if (vidix_name) - pre_init_err = vidix_preinit(vidix_name, &video_out_fbdev); + pre_init_err = vidix_preinit(vidix_name, + video_out_fbdev.old_functions); else #endif { @@ -1117,7 +1118,7 @@ static uint32_t get_image(mp_image_t *mpi) return VO_TRUE; } -static int control(uint32_t request, void *data, ...) +static int control(uint32_t request, void *data) { switch (request) { case VOCTRL_GET_IMAGE: @@ -1130,27 +1131,8 @@ static int control(uint32_t request, void *data, ...) if (vidix_name) { switch (request) { case VOCTRL_SET_EQUALIZER: - { - va_list ap; - int value; - - va_start(ap, data); - value = va_arg(ap, int); - va_end(ap); - - return vidix_control(request, data, value); - } case VOCTRL_GET_EQUALIZER: - { - va_list ap; - int *value; - - va_start(ap, data); - value = va_arg(ap, int*); - va_end(ap); - - return vidix_control(request, data, value); - } + return vidix_control(request, data); } } #endif diff --git a/libvo/vo_fbdev2.c b/libvo/vo_fbdev2.c index a18e9f2f47..2a64ed0612 100644 --- a/libvo/vo_fbdev2.c +++ b/libvo/vo_fbdev2.c @@ -413,7 +413,7 @@ static void uninit(void) fb_preinit(1); // so that later calls to preinit don't fail } -static int control(uint32_t request, void *data, ...) +static int control(uint32_t request, void *data) { switch (request) { case VOCTRL_QUERY_FORMAT: diff --git a/libvo/vo_ggi.c b/libvo/vo_ggi.c index 645bed2577..2be65696f5 100644 --- a/libvo/vo_ggi.c +++ b/libvo/vo_ggi.c @@ -83,6 +83,8 @@ static struct ggi_conf_s { } flushregion; int voflags; + + int depthonscreen; } ggi_conf; @@ -210,7 +212,7 @@ static int config(uint32_t width, uint32_t height, uint32_t d_width, ggiSetFlags(ggi_conf.drawvis, GGIFLAG_ASYNC); } - vo_depthonscreen = GT_DEPTH(mode.graphtype); + ggi_conf.depthonscreen = GT_DEPTH(mode.graphtype); vo_screenwidth = mode.virt.x; vo_screenheight = mode.virt.y; @@ -374,9 +376,9 @@ static int query_format(uint32_t format) | VFCAP_CSP_SUPPORTED_BY_HW | VFCAP_ACCEPT_STRIDE; - if ((!vo_depthonscreen || !vo_dbpp) && ggi_conf.vis) { + if ((!ggi_conf.depthonscreen || !vo_dbpp) && ggi_conf.vis) { if (ggiGetMode(ggi_conf.vis, &mode) == 0) { - vo_depthonscreen = GT_DEPTH(mode.graphtype); + ggi_conf.depthonscreen = GT_DEPTH(mode.graphtype); vo_dbpp = GT_SIZE(mode.graphtype); } if (GT_SCHEME(mode.graphtype) == GT_AUTO) { @@ -384,7 +386,7 @@ static int query_format(uint32_t format) } if (GT_SCHEME(mode.graphtype) != GT_TRUECOLOR) { mode.graphtype = GT_32BIT; - vo_depthonscreen = GT_DEPTH(mode.graphtype); + ggi_conf.depthonscreen = GT_DEPTH(mode.graphtype); vo_dbpp = GT_SIZE(mode.graphtype); } } @@ -468,7 +470,7 @@ static void uninit(void) ggiExit(); } -static int control(uint32_t request, void *data, ...) +static int control(uint32_t request, void *data) { switch (request) { case VOCTRL_QUERY_FORMAT: diff --git a/libvo/vo_gif89a.c b/libvo/vo_gif89a.c index b7a9894591..c51e303a7b 100644 --- a/libvo/vo_gif89a.c +++ b/libvo/vo_gif89a.c @@ -335,7 +335,7 @@ static int query_format(uint32_t format) return 0; } -static int control(uint32_t request, void *data, ...) +static int control(uint32_t request, void *data) { if (request == VOCTRL_QUERY_FORMAT) { return query_format(*((uint32_t*)data)); diff --git a/libvo/vo_gl.c b/libvo/vo_gl.c index 6126afa084..8b19e30d21 100644 --- a/libvo/vo_gl.c +++ b/libvo/vo_gl.c @@ -1095,7 +1095,7 @@ static const struct { {NULL, NULL, 0 } }; -static int control(uint32_t request, void *data, ...) +static int control(uint32_t request, void *data) { switch (request) { case VOCTRL_PAUSE: @@ -1130,14 +1130,14 @@ static int control(uint32_t request, void *data, ...) case VOCTRL_GUISUPPORT: return VO_TRUE; case VOCTRL_ONTOP: - vo_ontop(); + vo_gl_ontop(); return VO_TRUE; case VOCTRL_FULLSCREEN: vo_fullscreen(); resize(vo_dwidth, vo_dheight); return VO_TRUE; case VOCTRL_BORDER: - vo_border(); + vo_gl_border(global_vo); resize(vo_dwidth, vo_dheight); return VO_TRUE; case VOCTRL_GET_PANSCAN: @@ -1149,33 +1149,25 @@ static int control(uint32_t request, void *data, ...) return VO_TRUE; case VOCTRL_GET_EQUALIZER: if (image_format == IMGFMT_YV12) { + struct voctrl_get_equalizer_args *args = data; int i; - va_list va; - int *value; - va_start(va, data); - value = va_arg(va, int *); - va_end(va); for (i = 0; eq_map[i].name; i++) - if (strcmp(data, eq_map[i].name) == 0) break; + if (strcmp(args->name, eq_map[i].name) == 0) break; if (!(eq_map[i].supportmask & (1 << use_yuv))) break; - *value = *eq_map[i].value; + *args->valueptr = *eq_map[i].value; return VO_TRUE; } break; case VOCTRL_SET_EQUALIZER: if (image_format == IMGFMT_YV12) { + struct voctrl_set_equalizer_args *args = data; int i; - va_list va; - int value; - va_start(va, data); - value = va_arg(va, int); - va_end(va); for (i = 0; eq_map[i].name; i++) - if (strcmp(data, eq_map[i].name) == 0) break; + if (strcmp(args->name, eq_map[i].name) == 0) break; if (!(eq_map[i].supportmask & (1 << use_yuv))) break; - *eq_map[i].value = value; + *eq_map[i].value = args->value; update_yuvconv(); return VO_TRUE; } @@ -1183,6 +1175,12 @@ static int control(uint32_t request, void *data, ...) case VOCTRL_UPDATE_SCREENINFO: update_xinerama_info(); return VO_TRUE; + case VOCTRL_REDRAW_OSD: + if (vo_doublebuffering) + do_render(); + draw_osd(); + flip_page(); + return VO_TRUE; } return VO_NOTIMPL; } diff --git a/libvo/vo_gl2.c b/libvo/vo_gl2.c index 28afc77829..0b7393a6ef 100644 --- a/libvo/vo_gl2.c +++ b/libvo/vo_gl2.c @@ -876,7 +876,7 @@ static int preinit(const char *arg) return 0; } -static int control(uint32_t request, void *data, ...) +static int control(uint32_t request, void *data) { switch (request) { case VOCTRL_PAUSE: @@ -888,7 +888,7 @@ static int control(uint32_t request, void *data, ...) case VOCTRL_GUISUPPORT: return VO_TRUE; case VOCTRL_ONTOP: - vo_ontop(); + vo_gl_ontop(); return VO_TRUE; case VOCTRL_FULLSCREEN: vo_fullscreen(); @@ -897,7 +897,7 @@ static int control(uint32_t request, void *data, ...) resize(&vo_dwidth, &vo_dheight); return VO_TRUE; case VOCTRL_BORDER: - vo_border(); + vo_gl_border(global_vo); return VO_TRUE; case VOCTRL_GET_PANSCAN: return VO_TRUE; @@ -907,23 +907,13 @@ static int control(uint32_t request, void *data, ...) #ifndef GL_WIN32 case VOCTRL_SET_EQUALIZER: { - va_list ap; - int value; - - va_start(ap, data); - value = va_arg(ap, int); - va_end(ap); - return vo_x11_set_equalizer(data, value); + struct voctrl_set_equalizer_args *args = data; + return vo_x11_set_equalizer(args->name, args->value); } case VOCTRL_GET_EQUALIZER: { - va_list ap; - int *value; - - va_start(ap, data); - value = va_arg(ap, int *); - va_end(ap); - return vo_x11_get_equalizer(data, value); + struct voctrl_get_equalizer_args *args = data; + return vo_x11_get_equalizer(args->name, args->valueptr); } #endif case VOCTRL_UPDATE_SCREENINFO: diff --git a/libvo/vo_ivtv.c b/libvo/vo_ivtv.c index 05f37303d5..38b9ee7f4e 100644 --- a/libvo/vo_ivtv.c +++ b/libvo/vo_ivtv.c @@ -108,7 +108,7 @@ ivtv_reset (int blank_screen) } int -ivtv_write (unsigned char *data, int len) +ivtv_write (const unsigned char *data, int len) { if (ivtv_fd < 0) return 0; @@ -285,7 +285,7 @@ query_format (uint32_t format) } static int -control (uint32_t request, void *data, ...) +control (uint32_t request, void *data) { switch (request) { diff --git a/libvo/vo_jpeg.c b/libvo/vo_jpeg.c index e1a397eaf1..3d8fcc77f0 100644 --- a/libvo/vo_jpeg.c +++ b/libvo/vo_jpeg.c @@ -44,7 +44,7 @@ #include "mp_msg.h" #include "video_out.h" #include "video_out_internal.h" -#include "mplayer.h" /* for exit_player() */ +#include "mplayer.h" /* for exit_player_bad() */ #include "help_mp.h" /* ------------------------------------------------------------------------- */ @@ -121,17 +121,17 @@ static void jpeg_mkdir(char *buf, int verbose) { MSGTR_VO_GenericError, strerror(errno) ); mp_msg(MSGT_VO, MSGL_ERR, "%s: %s %s\n", info.short_name, MSGTR_VO_UnableToAccess,buf); - exit_player(MSGTR_Exit_error); + exit_player_bad(MSGTR_Exit_error); } if ( !S_ISDIR(stat_p.st_mode) ) { mp_msg(MSGT_VO, MSGL_ERR, "%s: %s %s\n", info.short_name, buf, MSGTR_VO_ExistsButNoDirectory); - exit_player(MSGTR_Exit_error); + exit_player_bad(MSGTR_Exit_error); } if ( !(stat_p.st_mode & S_IWUSR) ) { mp_msg(MSGT_VO, MSGL_ERR, "%s: %s - %s\n", info.short_name, buf, MSGTR_VO_DirExistsButNotWritable); - exit_player(MSGTR_Exit_error); + exit_player_bad(MSGTR_Exit_error); } mp_msg(MSGT_VO, MSGL_INFO, "%s: %s - %s\n", info.short_name, @@ -143,7 +143,7 @@ static void jpeg_mkdir(char *buf, int verbose) { MSGTR_VO_GenericError, strerror(errno) ); mp_msg(MSGT_VO, MSGL_ERR, "%s: %s - %s\n", info.short_name, buf, MSGTR_VO_CantCreateDirectory); - exit_player(MSGTR_Exit_error); + exit_player_bad(MSGTR_Exit_error); } /* end switch */ } else if ( verbose ) { mp_msg(MSGT_VO, MSGL_INFO, "%s: %s - %s\n", info.short_name, @@ -192,7 +192,7 @@ static uint32_t jpeg_write(uint8_t * name, uint8_t * buffer) mp_msg(MSGT_VO, MSGL_ERR, "%s: %s: %s\n", info.short_name, MSGTR_VO_GenericError, strerror(errno) ); - exit_player(MSGTR_Exit_error); + exit_player_bad(MSGTR_Exit_error); } cinfo.err = jpeg_std_error(&jerr); @@ -404,7 +404,7 @@ static int preinit(const char *arg) /* ------------------------------------------------------------------------- */ -static int control(uint32_t request, void *data, ...) +static int control(uint32_t request, void *data) { switch (request) { case VOCTRL_QUERY_FORMAT: diff --git a/libvo/vo_macosx.m b/libvo/vo_macosx.m index 1cd1d43b76..2c7bed9e53 100644 --- a/libvo/vo_macosx.m +++ b/libvo/vo_macosx.m @@ -52,6 +52,7 @@ #include "input/mouse.h" #include "osdep/keycodes.h" +#include "mp_fifo.h" //Cocoa NSDistantObject *mplayerosxProxy; @@ -88,8 +89,6 @@ static uint32_t image_format; static int isFullscreen; static int isOntop; static int isRootwin; -extern float monitor_aspect; -extern float movie_aspect; static float old_movie_aspect; extern int enable_mouse_movements; @@ -416,7 +415,7 @@ static int preinit(const char *arg) return 0; } -static int control(uint32_t request, void *data, ...) +static int control(uint32_t request, void *data) { switch (request) { @@ -1065,7 +1064,7 @@ static int control(uint32_t request, void *data, ...) snprintf(cmdstr, sizeof(cmdstr), "set_mouse_pos %i %i", (int)(vo_fs ? p.x : (p.x - textureFrame.origin.x)), (int)(vo_fs ? [self frame].size.height - p.y: (NSMaxY(textureFrame) - p.y))); - mp_input_queue_cmd(mp_input_parse_cmd(cmdstr)); + mp_input_queue_cmd(global_vo->input_ctx, mp_input_parse_cmd(cmdstr)); } } } diff --git a/libvo/vo_md5sum.c b/libvo/vo_md5sum.c index 4fd9cdd618..be325f133a 100644 --- a/libvo/vo_md5sum.c +++ b/libvo/vo_md5sum.c @@ -40,7 +40,7 @@ #include "mp_msg.h" #include "video_out.h" #include "video_out_internal.h" -#include "mplayer.h" /* for exit_player() */ +#include "mplayer.h" /* for exit_player_bad() */ #include "help_mp.h" #include "libavutil/md5.h" @@ -86,7 +86,7 @@ int framenum = 0; static void md5sum_write_error(void) { mp_msg(MSGT_VO, MSGL_ERR, MSGTR_ErrorWritingFile, info.short_name); - exit_player(MSGTR_Exit_error); + exit_player_bad(MSGTR_Exit_error); } /* ------------------------------------------------------------------------- */ @@ -152,7 +152,7 @@ static int config(uint32_t width, uint32_t height, uint32_t d_width, MSGTR_VO_CantCreateFile); mp_msg(MSGT_VO, MSGL_ERR, "%s: %s: %s\n", info.short_name, MSGTR_VO_GenericError, strerror(errno) ); - exit_player(MSGTR_Exit_error); + exit_player_bad(MSGTR_Exit_error); } return 0; @@ -264,7 +264,7 @@ static int query_format(uint32_t format) /* ------------------------------------------------------------------------- */ -static int control(uint32_t request, void *data, ...) +static int control(uint32_t request, void *data) { switch (request) { case VOCTRL_QUERY_FORMAT: diff --git a/libvo/vo_mpegpes.c b/libvo/vo_mpegpes.c index 35d5f188ef..3ff03bf205 100644 --- a/libvo/vo_mpegpes.c +++ b/libvo/vo_mpegpes.c @@ -185,7 +185,7 @@ static void draw_osd(void) } -static int my_write(unsigned char* data,int len){ +static int my_write(const unsigned char* data,int len){ int orig_len = len; #ifdef CONFIG_DVB #define NFD 2 @@ -220,15 +220,10 @@ static int my_write(unsigned char* data,int len){ return orig_len; } -void send_pes_packet(unsigned char* data,int len,int id,int timestamp){ +static void send_pes_packet(unsigned char* data,int len,int id,int timestamp){ send_mpeg_pes_packet (data, len, id, timestamp, 1, my_write); } -void send_lpcm_packet(unsigned char* data,int len,int id,unsigned int timestamp,int freq_id){ - send_mpeg_lpcm_packet(data, len, id, timestamp, freq_id, my_write); -} - - static int draw_frame(uint8_t * src[]) { vo_mpegpes_t *p=(vo_mpegpes_t *)src[0]; @@ -266,7 +261,7 @@ static void check_events(void) { } -static int control(uint32_t request, void *data, ...) +static int control(uint32_t request, void *data) { switch (request) { case VOCTRL_QUERY_FORMAT: diff --git a/libvo/vo_null.c b/libvo/vo_null.c index 33c86580c5..81438898ed 100644 --- a/libvo/vo_null.c +++ b/libvo/vo_null.c @@ -98,7 +98,7 @@ static int preinit(const char *arg) return 0; } -static int control(uint32_t request, void *data, ...) +static int control(uint32_t request, void *data) { switch (request) { case VOCTRL_QUERY_FORMAT: diff --git a/libvo/vo_png.c b/libvo/vo_png.c index 5a2edf7ed9..0e28b0e2e0 100644 --- a/libvo/vo_png.c +++ b/libvo/vo_png.c @@ -26,9 +26,6 @@ #include <stdlib.h> #include <string.h> #include <errno.h> -#include <sys/stat.h> -#include <sys/types.h> -#include <unistd.h> #include <png.h> @@ -39,9 +36,6 @@ #include "video_out.h" #include "video_out_internal.h" #include "subopt-helper.h" -#include "mplayer.h" - -#define BUFLENGTH 512 static const vo_info_t info = { @@ -54,7 +48,6 @@ static const vo_info_t info = const LIBVO_EXTERN (png) static int z_compression = Z_NO_COMPRESSION; -static char *png_outdir = NULL; static int framenum = 0; static int use_alpha; @@ -65,56 +58,9 @@ struct pngdata { enum {OK,ERROR} status; }; -static void png_mkdir(char *buf, int verbose) { - struct stat stat_p; - -#ifndef __MINGW32__ - if ( mkdir(buf, 0755) < 0 ) { -#else - if ( mkdir(buf) < 0 ) { -#endif - switch (errno) { /* use switch in case other errors need to be caught - and handled in the future */ - case EEXIST: - if ( stat(buf, &stat_p ) < 0 ) { - mp_msg(MSGT_VO, MSGL_ERR, "%s: %s: %s\n", info.short_name, - MSGTR_VO_GenericError, strerror(errno) ); - mp_msg(MSGT_VO, MSGL_ERR, "%s: %s %s\n", info.short_name, - MSGTR_VO_UnableToAccess,buf); - exit_player(MSGTR_Exit_error); - } - if ( !S_ISDIR(stat_p.st_mode) ) { - mp_msg(MSGT_VO, MSGL_ERR, "%s: %s %s\n", info.short_name, - buf, MSGTR_VO_ExistsButNoDirectory); - exit_player(MSGTR_Exit_error); - } - if ( !(stat_p.st_mode & S_IWUSR) ) { - mp_msg(MSGT_VO, MSGL_ERR, "%s: %s - %s\n", info.short_name, - buf, MSGTR_VO_DirExistsButNotWritable); - exit_player(MSGTR_Exit_error); - } - - mp_msg(MSGT_VO, MSGL_INFO, "%s: %s - %s\n", info.short_name, - buf, MSGTR_VO_DirExistsAndIsWritable); - break; - - default: - mp_msg(MSGT_VO, MSGL_ERR, "%s: %s: %s\n", info.short_name, - MSGTR_VO_GenericError, strerror(errno) ); - mp_msg(MSGT_VO, MSGL_ERR, "%s: %s - %s\n", info.short_name, - buf, MSGTR_VO_CantCreateDirectory); - exit_player(MSGTR_Exit_error); - } /* end switch */ - } else if ( verbose ) { - mp_msg(MSGT_VO, MSGL_INFO, "%s: %s - %s\n", info.short_name, - buf, MSGTR_VO_DirectoryCreateSuccess); - } /* end if */ -} - static int config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uint32_t flags, char *title, uint32_t format) { - char buf[BUFLENGTH]; if(z_compression == 0) { mp_msg(MSGT_VO,MSGL_INFO, MSGTR_LIBVO_PNG_Warning1); @@ -122,8 +68,6 @@ config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uin mp_msg(MSGT_VO,MSGL_INFO, MSGTR_LIBVO_PNG_Warning3); } - snprintf(buf, BUFLENGTH, "%s", png_outdir); - png_mkdir(buf, 1); mp_msg(MSGT_VO,MSGL_DBG2, "PNG Compression level %i\n", z_compression); return 0; @@ -220,7 +164,7 @@ static uint32_t draw_image(mp_image_t* mpi){ // if -dr or -slices then do nothing: if(mpi->flags&(MP_IMGFLAG_DIRECT|MP_IMGFLAG_DRAW_CALLBACK)) return VO_TRUE; - snprintf (buf, 100, "%s/%08d.png", png_outdir, ++framenum); + snprintf (buf, 100, "%08d.png", ++framenum); png = create_png(buf, mpi->w, mpi->h, IMGFMT_IS_BGR(mpi->imgfmt)); @@ -274,12 +218,7 @@ query_format(uint32_t format) return 0; } -static void uninit(void){ - if (png_outdir) { - free(png_outdir); - png_outdir = NULL; - } -} +static void uninit(void){} static void check_events(void){} @@ -293,14 +232,12 @@ static int int_zero_to_nine(int *sh) static opt_t subopts[] = { {"alpha", OPT_ARG_BOOL, &use_alpha, NULL, 0}, {"z", OPT_ARG_INT, &z_compression, (opt_test_f)int_zero_to_nine}, - {"outdir", OPT_ARG_MSTRZ, &png_outdir, NULL, 0}, {NULL} }; static int preinit(const char *arg) { z_compression = 0; - png_outdir = strdup("."); use_alpha = 0; if (subopt_parse(arg, subopts) != 0) { return -1; @@ -308,7 +245,7 @@ static int preinit(const char *arg) return 0; } -static int control(uint32_t request, void *data, ...) +static int control(uint32_t request, void *data) { switch (request) { case VOCTRL_DRAW_IMAGE: diff --git a/libvo/vo_pnm.c b/libvo/vo_pnm.c index ba88db29e9..a6e4431331 100644 --- a/libvo/vo_pnm.c +++ b/libvo/vo_pnm.c @@ -39,7 +39,7 @@ #include "mp_msg.h" #include "video_out.h" #include "video_out_internal.h" -#include "mplayer.h" /* for exit_player() */ +#include "mplayer.h" /* for exit_player_bad() */ #include "help_mp.h" /* ------------------------------------------------------------------------- */ @@ -98,7 +98,7 @@ char *pnm_file_extension = NULL; static void pnm_write_error(void) { mp_msg(MSGT_VO, MSGL_ERR, MSGTR_ErrorWritingFile, info.short_name); - exit_player(MSGTR_Exit_error); + exit_player_bad(MSGTR_Exit_error); } /* ------------------------------------------------------------------------- */ @@ -214,17 +214,17 @@ static void pnm_mkdir(char *buf, int verbose) { MSGTR_VO_GenericError, strerror(errno) ); mp_msg(MSGT_VO, MSGL_ERR, "%s: %s %s\n", info.short_name, MSGTR_VO_UnableToAccess,buf); - exit_player(MSGTR_Exit_error); + exit_player_bad(MSGTR_Exit_error); } if ( !S_ISDIR(stat_p.st_mode) ) { mp_msg(MSGT_VO, MSGL_ERR, "%s: %s %s\n", info.short_name, buf, MSGTR_VO_ExistsButNoDirectory); - exit_player(MSGTR_Exit_error); + exit_player_bad(MSGTR_Exit_error); } if ( !(stat_p.st_mode & S_IWUSR) ) { mp_msg(MSGT_VO, MSGL_ERR, "%s: %s - %s\n", info.short_name, buf, MSGTR_VO_DirExistsButNotWritable); - exit_player(MSGTR_Exit_error); + exit_player_bad(MSGTR_Exit_error); } if (strcmp(buf, ".") != 0) { @@ -238,7 +238,7 @@ static void pnm_mkdir(char *buf, int verbose) { MSGTR_VO_GenericError, strerror(errno) ); mp_msg(MSGT_VO, MSGL_ERR, "%s: %s - %s\n", info.short_name, buf, MSGTR_VO_CantCreateDirectory); - exit_player(MSGTR_Exit_error); + exit_player_bad(MSGTR_Exit_error); } /* end switch */ } else if ( verbose ) { mp_msg(MSGT_VO, MSGL_INFO, "%s: %s - %s\n", info.short_name, @@ -442,7 +442,7 @@ static void pnm_write_image(mp_image_t *mpi) if (!mpi) { mp_msg(MSGT_VO, MSGL_ERR, "%s: No image data suplied to video output driver\n", info.short_name ); - exit_player(MSGTR_Exit_error); + exit_player_bad(MSGTR_Exit_error); } /* Start writing to new subdirectory after a certain amount of frames */ @@ -474,7 +474,7 @@ static void pnm_write_image(mp_image_t *mpi) mp_msg(MSGT_VO, MSGL_ERR, "%s: %s: %s\n", info.short_name, MSGTR_VO_GenericError, strerror(errno) ); - exit_player(MSGTR_Exit_error); + exit_player_bad(MSGTR_Exit_error); } pnm_write_pnm(outfile, mpi); @@ -542,7 +542,7 @@ static int query_format(uint32_t format) /* ------------------------------------------------------------------------- */ -static int control(uint32_t request, void *data, ...) +static int control(uint32_t request, void *data) { switch (request) { case VOCTRL_QUERY_FORMAT: diff --git a/libvo/vo_quartz.c b/libvo/vo_quartz.c index edc99ab445..97ca656b8d 100644 --- a/libvo/vo_quartz.c +++ b/libvo/vo_quartz.c @@ -87,8 +87,6 @@ static int EnterMoviesDone = 0; static int get_image_done = 0; static int vo_quartz_fs; // we are in fullscreen -extern float monitor_aspect; -extern float movie_aspect; static float old_movie_aspect; static int winLevel = 1; @@ -1273,7 +1271,7 @@ static uint32_t get_yuv_image(mp_image_t * mpi) return VO_FALSE; } -static int control(uint32_t request, void *data, ...) +static int control(uint32_t request, void *data) { switch (request) { diff --git a/libvo/vo_s3fb.c b/libvo/vo_s3fb.c index 930dcc80c4..da2408f146 100644 --- a/libvo/vo_s3fb.c +++ b/libvo/vo_s3fb.c @@ -521,7 +521,7 @@ static uint32_t get_image(mp_image_t *mpi) return VO_TRUE; } -static int control(uint32_t request, void *data, ...) +static int control(uint32_t request, void *data) { switch(request) { case VOCTRL_GET_IMAGE: diff --git a/libvo/vo_sdl.c b/libvo/vo_sdl.c index 26b17776fd..ab9ab8935e 100644 --- a/libvo/vo_sdl.c +++ b/libvo/vo_sdl.c @@ -1635,7 +1635,7 @@ static uint32_t get_image(mp_image_t *mpi) return VO_FALSE; } -static int control(uint32_t request, void *data, ...) +static int control(uint32_t request, void *data) { struct sdl_priv_s *priv = &sdl_priv; switch (request) { diff --git a/libvo/vo_svga.c b/libvo/vo_svga.c index f745c41c29..b72a6aded7 100644 --- a/libvo/vo_svga.c +++ b/libvo/vo_svga.c @@ -152,7 +152,7 @@ char s[64]; vidix_name[i-5]=0; if(arg[i]==':')i++; arg+=i; - vidix_preinit(vidix_name, &video_out_svga); + vidix_preinit(vidix_name, video_out_svga.old_functions); } #endif if(!strncmp(arg,"sq",2)) { @@ -367,7 +367,7 @@ static int find_best_svga_mode(int req_w,int req_h, int req_bpp){ return bestmode; } -static int control(uint32_t request, void *data, ...) +static int control(uint32_t request, void *data) { switch (request) { case VOCTRL_QUERY_FORMAT: @@ -379,33 +379,8 @@ static int control(uint32_t request, void *data, ...) } #ifdef CONFIG_VIDIX - if (vidix_name[0]) { - switch (request) { - case VOCTRL_SET_EQUALIZER: - { - va_list ap; - int value; - - va_start(ap, data); - value = va_arg(ap, int); - va_end(ap); - - return vidix_control(request, data, value); - } - case VOCTRL_GET_EQUALIZER: - { - va_list ap; - int *value; - - va_start(ap, data); - value = va_arg(ap, int*); - va_end(ap); - - return vidix_control(request, data, value); - } - } + if (vidix_name[0]) return vidix_control(request, data); - } #endif return VO_NOTIMPL; diff --git a/libvo/vo_tdfx_vid.c b/libvo/vo_tdfx_vid.c index 5c7f917d4e..3112a82540 100644 --- a/libvo/vo_tdfx_vid.c +++ b/libvo/vo_tdfx_vid.c @@ -644,7 +644,7 @@ static uint32_t set_colorkey(mp_colorkey_t* colork) { return VO_TRUE; } -static int control(uint32_t request, void *data, ...) +static int control(uint32_t request, void *data) { switch (request) { case VOCTRL_QUERY_FORMAT: diff --git a/libvo/vo_tdfxfb.c b/libvo/vo_tdfxfb.c index 1b63147817..c40cae7b82 100644 --- a/libvo/vo_tdfxfb.c +++ b/libvo/vo_tdfxfb.c @@ -496,7 +496,7 @@ static uint32_t get_image(mp_image_t *mpi) return VO_TRUE; } -static int control(uint32_t request, void *data, ...) +static int control(uint32_t request, void *data) { switch(request) { case VOCTRL_GET_IMAGE: diff --git a/libvo/vo_tga.c b/libvo/vo_tga.c index 0b338f994c..70408cc0e4 100644 --- a/libvo/vo_tga.c +++ b/libvo/vo_tga.c @@ -260,7 +260,7 @@ static int preinit(const char *arg) return 0; } -static int control(uint32_t request, void *data, ...) +static int control(uint32_t request, void *data) { switch (request) { case VOCTRL_DRAW_IMAGE: diff --git a/libvo/vo_v4l2.c b/libvo/vo_v4l2.c index 7cecfd75da..7157c68430 100644 --- a/libvo/vo_v4l2.c +++ b/libvo/vo_v4l2.c @@ -69,7 +69,7 @@ static const vo_info_t info = const LIBVO_EXTERN (v4l2) int -v4l2_write (unsigned char *data, int len) +v4l2_write (const unsigned char *data, int len) { if (v4l2_fd < 0) return 0; @@ -253,7 +253,7 @@ query_format (uint32_t format) } static int -control (uint32_t request, void *data, ...) +control (uint32_t request, void *data) { switch (request) { diff --git a/libvo/vo_vesa.c b/libvo/vo_vesa.c index d1924fe18a..a5c3c899f3 100644 --- a/libvo/vo_vesa.c +++ b/libvo/vo_vesa.c @@ -1087,7 +1087,8 @@ static int preinit(const char *arg) if(arg) subdev_flags = parseSubDevice(arg); if(lvo_name) pre_init_err = vlvo_preinit(lvo_name); #ifdef CONFIG_VIDIX - else if(vidix_name) pre_init_err = vidix_preinit(vidix_name,&video_out_vesa); + else if(vidix_name) pre_init_err = vidix_preinit(vidix_name, + video_out_vesa.old_functions); #endif // check if we can open /dev/mem (it will be opened later in config(), but if we // detect now that we can't we can exit cleanly) @@ -1101,7 +1102,7 @@ static int preinit(const char *arg) return pre_init_err; } -static int control(uint32_t request, void *data, ...) +static int control(uint32_t request, void *data) { switch (request) { case VOCTRL_QUERY_FORMAT: @@ -1109,33 +1110,8 @@ static int control(uint32_t request, void *data, ...) } #ifdef CONFIG_VIDIX - if (vidix_name) { - switch (request) { - case VOCTRL_SET_EQUALIZER: - { - va_list ap; - int value; - - va_start(ap, data); - value = va_arg(ap, int); - va_end(ap); - - return vidix_control(request, data, (int *)value); - } - case VOCTRL_GET_EQUALIZER: - { - va_list ap; - int *value; - - va_start(ap, data); - value = va_arg(ap, int*); - va_end(ap); - - return vidix_control(request, data, value); - } - } + if (vidix_name) return vidix_control(request, data); - } #endif return VO_NOTIMPL; diff --git a/libvo/vo_wii.c b/libvo/vo_wii.c index 030b19dd05..8999852d80 100644 --- a/libvo/vo_wii.c +++ b/libvo/vo_wii.c @@ -351,7 +351,7 @@ static uint32_t get_image(mp_image_t *mpi) return VO_TRUE; } -static int control(uint32_t request, void *data, ...) +static int control(uint32_t request, void *data) { if (request == VOCTRL_GET_IMAGE) return get_image(data); diff --git a/libvo/vo_winvidix.c b/libvo/vo_winvidix.c index 337863fbf8..054e13730e 100644 --- a/libvo/vo_winvidix.c +++ b/libvo/vo_winvidix.c @@ -57,6 +57,7 @@ LIBVO_EXTERN(winvidix) /* VIDIX related */ static char *vidix_name; +static int depthonscreen; /* Image parameters */ static uint32_t image_width; static uint32_t image_height; @@ -129,7 +130,7 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM l /*update vidix*/ /* FIXME: implement runtime resize/move if possible, this way is very ugly! */ vidix_stop(); - if(vidix_init(image_width, image_height, vo_dx, vo_dy, vo_dwidth, vo_dheight, image_format, vo_depthonscreen, vo_screenwidth, vo_screenheight) != 0) + if(vidix_init(image_width, image_height, vo_dx, vo_dy, vo_dwidth, vo_dheight, image_format, depthonscreen, vo_screenwidth, vo_screenheight) != 0) mp_msg(MSGT_VO, MSGL_FATAL, "Can't initialize VIDIX driver: %s\n", strerror(errno)); /*set colorkey*/ vidix_start(); @@ -203,7 +204,7 @@ static int config(uint32_t width, uint32_t height, uint32_t d_width,uint32_t d_h image_format = format; vo_screenwidth = GetSystemMetrics(SM_CXSCREEN); vo_screenheight = GetSystemMetrics(SM_CYSCREEN); - vo_depthonscreen = GetDeviceCaps(GetDC(GetDesktopWindow()),BITSPIXEL); + depthonscreen = GetDeviceCaps(GetDC(GetDesktopWindow()),BITSPIXEL); aspect_save_orig(width, height); @@ -336,13 +337,13 @@ static int preinit(const char *arg){ vidix_name = NULL; } - if (vidix_preinit(vidix_name, &video_out_winvidix) != 0) + if (vidix_preinit(vidix_name, video_out_winvidix.old_functions) != 0) return 1; return 0; } -static int control(uint32_t request, void *data, ...){ +static int control(uint32_t request, void *data){ switch (request) { case VOCTRL_FULLSCREEN: if(!vo_fs){vo_fs=1;ShowWindow(hWndFS,SW_SHOW);SetForegroundWindow(hWndFS);} @@ -350,28 +351,6 @@ static int control(uint32_t request, void *data, ...){ break; case VOCTRL_QUERY_FORMAT: return query_format(*((uint32_t*)data)); - case VOCTRL_SET_EQUALIZER: - { - va_list ap; - int value; - - va_start(ap, data); - value = va_arg(ap, int); - va_end(ap); - - return vidix_control(request, data, (int *)value); - } - case VOCTRL_GET_EQUALIZER: - { - va_list ap; - int *value; - - va_start(ap, data); - value = va_arg(ap, int*); - va_end(ap); - - return vidix_control(request, data, value); - } } return vidix_control(request, data); // return VO_NOTIMPL; diff --git a/libvo/vo_x11.c b/libvo/vo_x11.c index d06c4394ed..4e6b1b79fb 100644 --- a/libvo/vo_x11.c +++ b/libvo/vo_x11.c @@ -667,7 +667,7 @@ static int preinit(const char *arg) return 0; } -static int control(uint32_t request, void *data, ...) +static int control(uint32_t request, void *data) { switch (request) { @@ -687,25 +687,13 @@ static int control(uint32_t request, void *data, ...) return VO_TRUE; case VOCTRL_SET_EQUALIZER: { - va_list ap; - int value; - - va_start(ap, data); - value = va_arg(ap, int); - - va_end(ap); - return vo_x11_set_equalizer(data, value); + struct voctrl_set_equalizer_args *args = data; + return vo_x11_set_equalizer(args->name, args->value); } case VOCTRL_GET_EQUALIZER: { - va_list ap; - int *value; - - va_start(ap, data); - value = va_arg(ap, int *); - - va_end(ap); - return vo_x11_get_equalizer(data, value); + struct voctrl_get_equalizer_args *args = data; + return vo_x11_get_equalizer(args->name, args->valueptr); } case VOCTRL_ONTOP: vo_x11_ontop(); diff --git a/libvo/vo_xover.c b/libvo/vo_xover.c index f20d60f1d6..4935ca0fd7 100644 --- a/libvo/vo_xover.c +++ b/libvo/vo_xover.c @@ -82,8 +82,8 @@ static uint32_t window_width, window_height; static uint32_t drwX, drwY, drwWidth, drwHeight, drwBorderWidth, drwDepth, drwcX, drwcY, dwidth, dheight; -static const vo_functions_t* sub_vo = NULL; - +static const struct vo_old_functions *sub_vo = NULL; +static const struct vo_info_s *sub_info; static void set_window(int force_update) { @@ -224,7 +224,7 @@ static int config(uint32_t width, uint32_t height, uint32_t d_width, mp_colorkey_t colork; char _title[255]; - sprintf(_title,"MPlayer %s X11 Overlay",sub_vo->info->name); + sprintf(_title,"MPlayer %s X11 Overlay", sub_info->name); title = _title; panscan_init(); @@ -378,10 +378,10 @@ static void uninit(void) sub_vo = NULL; vo_x11_uninit(); // Restore our callbacks - video_out_xover.draw_frame = draw_frame; - video_out_xover.draw_slice = draw_slice; - video_out_xover.flip_page = flip_page; - video_out_xover.draw_osd = draw_osd; + video_out_xover.old_functions->draw_frame = draw_frame; + video_out_xover.old_functions->draw_slice = draw_slice; + video_out_xover.old_functions->flip_page = flip_page; + video_out_xover.old_functions->draw_osd = draw_osd; } static int preinit(const char *arg) @@ -393,35 +393,38 @@ static int preinit(const char *arg) return 1; } - for(i = 0 ; video_out_drivers[i] != NULL ; i++) { - if(!strcmp(video_out_drivers[i]->info->short_name,arg) && - strcmp(video_out_drivers[i]->info->short_name,"xover")) + const struct vo_driver *candidate; + for(i = 0; (candidate = video_out_drivers[i]) != NULL; i++) + if (!candidate->is_new && !strcmp(candidate->info->short_name,arg) && + strcmp(candidate->info->short_name,"xover")) break; - } - if(!video_out_drivers[i]) { + if (!candidate) { mp_msg(MSGT_VO, MSGL_ERR, "VO XOverlay: Subdriver %s not found\n", arg); return 1; } - if(video_out_drivers[i]->control(VOCTRL_XOVERLAY_SUPPORT,NULL) != VO_TRUE) { + + const struct vo_old_functions *functions = candidate->old_functions; + if (functions->control(VOCTRL_XOVERLAY_SUPPORT,NULL) != VO_TRUE) { mp_msg(MSGT_VO, MSGL_ERR, "VO XOverlay: %s doesn't support XOverlay\n", arg); return 1; } // X11 init if (!vo_init()) return VO_FALSE; - if(video_out_drivers[i]->preinit(NULL)) { + if(functions->preinit(NULL)) { mp_msg(MSGT_VO, MSGL_ERR, "VO XOverlay: Subvo init failed\n"); return 1; } - sub_vo = video_out_drivers[i]; + sub_vo = functions; + sub_info = candidate->info; // Setup the sub vo callbacks - video_out_xover.draw_frame = sub_vo->draw_frame; - video_out_xover.draw_slice = sub_vo->draw_slice; - video_out_xover.flip_page = sub_vo->flip_page; - video_out_xover.draw_osd = sub_vo->draw_osd; + video_out_xover.old_functions->draw_frame = sub_vo->draw_frame; + video_out_xover.old_functions->draw_slice = sub_vo->draw_slice; + video_out_xover.old_functions->flip_page = sub_vo->flip_page; + video_out_xover.old_functions->draw_osd = sub_vo->draw_osd; return 0; } -static int control(uint32_t request, void *data, ...) +static int control(uint32_t request, void *data) { if(!sub_vo) return VO_ERROR; switch (request) { @@ -443,7 +446,6 @@ static int control(uint32_t request, void *data, ...) } return VO_TRUE; default: - // Safe atm bcs nothing use more than 1 arg return sub_vo->control(request,data); } return VO_NOTIMPL; diff --git a/libvo/vo_xv.c b/libvo/vo_xv.c index ddde21a402..c6bbcdf347 100644 --- a/libvo/vo_xv.c +++ b/libvo/vo_xv.c @@ -37,13 +37,18 @@ Buffer allocation: #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <stdint.h> +#include <stdbool.h> #include "config.h" +#include "options.h" +#include "talloc.h" #include "mp_msg.h" #include "help_mp.h" #include "video_out.h" -#include "video_out_internal.h" - +#include "libmpcodecs/vfcap.h" +#include "libmpcodecs/mp_image.h" +#include "osd.h" #include <X11/Xlib.h> #include <X11/Xutil.h> @@ -58,6 +63,7 @@ Buffer allocation: #include "subopt-helper.h" #include "input/input.h" +#include "mp_fifo.h" #ifdef CONFIG_GUI #include "gui/interface.h" @@ -72,153 +78,167 @@ static const vo_info_t info = { "" }; -const LIBVO_EXTERN(xv) #ifdef HAVE_SHM #include <sys/ipc.h> #include <sys/shm.h> #include <X11/extensions/XShm.h> - -static XShmSegmentInfo Shminfo[NUM_BUFFERS]; -static int Shmem_Flag; #endif // Note: depends on the inclusion of X11/extensions/XShm.h #include <X11/extensions/Xv.h> #include <X11/extensions/Xvlib.h> -// FIXME: dynamically allocate this stuff -static void allocate_xvimage(int); -static unsigned int ver, rel, req, ev, err; -static unsigned int formats, adaptors, xv_format; -static XvAdaptorInfo *ai = NULL; -static XvImageFormatValues *fo=NULL; - -static int current_buf = 0; -static int current_ip_buf = 0; -static int num_buffers = 1; // default -static int visible_buf = -1; // -1 means: no buffer was drawn yet -static XvImage *xvimage[NUM_BUFFERS]; - - -static uint32_t image_width; -static uint32_t image_height; -static uint32_t image_format; - -static int int_pause; +struct xvctx { + XvAdaptorInfo *ai; + XvImageFormatValues *fo; + unsigned int formats, adaptors, xv_format; + int current_buf; + int current_ip_buf; + int num_buffers; + int total_buffers; + int have_visible_image_copy; + int have_next_image_copy; + int unchanged_visible_image; + int unchanged_next_image; + int visible_buf; + XvImage *xvimage[NUM_BUFFERS + 1]; + uint32_t image_width; + uint32_t image_height; + uint32_t image_format; + int is_paused; + struct vo_rect src_rect; + struct vo_rect dst_rect; + uint32_t max_width, max_height; // zero means: not set + int event_fd_registered; // for uninit called from preinit + int mode_switched; + int osd_objects_drawn; + void (*draw_alpha_fnc)(void *ctx, int x0, int y0, int w, int h, + unsigned char *src, unsigned char *srca, + int stride); +#ifdef HAVE_SHM + XShmSegmentInfo Shminfo[NUM_BUFFERS]; + int Shmem_Flag; +#endif +}; -static struct vo_rect src_rect; -static struct vo_rect dst_rect; -static uint32_t max_width = 0, max_height = 0; // zero means: not set +static void allocate_xvimage(struct vo *, int); -static void (*draw_alpha_fnc) (int x0, int y0, int w, int h, - unsigned char *src, unsigned char *srca, - int stride); -static void draw_alpha_yv12(int x0, int y0, int w, int h, +static void draw_alpha_yv12(void *p, int x0, int y0, int w, int h, unsigned char *src, unsigned char *srca, int stride) { - x0 += image_width * (vo_panscan_x >> 1) / (vo_dwidth + vo_panscan_x); + struct vo *vo = p; + struct xvctx *ctx = vo->priv; + x0 += ctx->image_width * (vo->panscan_x >> 1) + / (vo->dwidth + vo->panscan_x); vo_draw_alpha_yv12(w, h, src, srca, stride, - xvimage[current_buf]->data + - xvimage[current_buf]->offsets[0] + - xvimage[current_buf]->pitches[0] * y0 + x0, - xvimage[current_buf]->pitches[0]); + ctx->xvimage[ctx->current_buf]->data + + ctx->xvimage[ctx->current_buf]->offsets[0] + + ctx->xvimage[ctx->current_buf]->pitches[0] * y0 + x0, + ctx->xvimage[ctx->current_buf]->pitches[0]); + ctx->osd_objects_drawn++; } -static void draw_alpha_yuy2(int x0, int y0, int w, int h, +static void draw_alpha_yuy2(void *p, int x0, int y0, int w, int h, unsigned char *src, unsigned char *srca, int stride) { - x0 += image_width * (vo_panscan_x >> 1) / (vo_dwidth + vo_panscan_x); + struct vo *vo = p; + struct xvctx *ctx = vo->priv; + x0 += ctx->image_width * (vo->panscan_x >> 1) + / (vo->dwidth + vo->panscan_x); vo_draw_alpha_yuy2(w, h, src, srca, stride, - xvimage[current_buf]->data + - xvimage[current_buf]->offsets[0] + - xvimage[current_buf]->pitches[0] * y0 + 2 * x0, - xvimage[current_buf]->pitches[0]); + ctx->xvimage[ctx->current_buf]->data + + ctx->xvimage[ctx->current_buf]->offsets[0] + + ctx->xvimage[ctx->current_buf]->pitches[0] * y0 + 2 * x0, + ctx->xvimage[ctx->current_buf]->pitches[0]); + ctx->osd_objects_drawn++; } -static void draw_alpha_uyvy(int x0, int y0, int w, int h, +static void draw_alpha_uyvy(void *p, int x0, int y0, int w, int h, unsigned char *src, unsigned char *srca, int stride) { - x0 += image_width * (vo_panscan_x >> 1) / (vo_dwidth + vo_panscan_x); + struct vo *vo = p; + struct xvctx *ctx = vo->priv; + x0 += ctx->image_width * (vo->panscan_x >> 1) + / (vo->dwidth + vo->panscan_x); vo_draw_alpha_yuy2(w, h, src, srca, stride, - xvimage[current_buf]->data + - xvimage[current_buf]->offsets[0] + - xvimage[current_buf]->pitches[0] * y0 + 2 * x0 + 1, - xvimage[current_buf]->pitches[0]); + ctx->xvimage[ctx->current_buf]->data + + ctx->xvimage[ctx->current_buf]->offsets[0] + + ctx->xvimage[ctx->current_buf]->pitches[0] * y0 + 2 * x0 + 1, + ctx->xvimage[ctx->current_buf]->pitches[0]); + ctx->osd_objects_drawn++; } -static void draw_alpha_null(int x0, int y0, int w, int h, +static void draw_alpha_null(void *p, int x0, int y0, int w, int h, unsigned char *src, unsigned char *srca, int stride) { } -static void deallocate_xvimage(int foo); +static void deallocate_xvimage(struct vo *vo, int foo); -static void resize(void) +static void resize(struct vo *vo) { - calc_src_dst_rects(image_width, image_height, &src_rect, &dst_rect, NULL); - vo_x11_clearwindow_part(mDisplay, vo_window, dst_rect.width, dst_rect.height, 1); - vo_xv_draw_colorkey(dst_rect.left, dst_rect.top, dst_rect.width, dst_rect.height); + struct xvctx *ctx = vo->priv; + + calc_src_dst_rects(vo, ctx->image_width, ctx->image_height, &ctx->src_rect, + &ctx->dst_rect, NULL); + struct vo_rect *dst = &ctx->dst_rect; + vo_x11_clearwindow_part(vo, vo->x11->window, dst->width, dst->height, 1); + vo_xv_draw_colorkey(vo, dst->left, dst->top, dst->width, dst->height); } /* * connect to server, create and map window, * allocate colors and (shared) memory */ -static int config(uint32_t width, uint32_t height, uint32_t d_width, - uint32_t d_height, uint32_t flags, char *title, - uint32_t format) +static int config(struct vo *vo, uint32_t width, uint32_t height, + uint32_t d_width, uint32_t d_height, uint32_t flags, + char *title, uint32_t format) { + struct MPOpts *opts = vo->opts; + struct vo_x11_state *x11 = vo->x11; XVisualInfo vinfo; XSetWindowAttributes xswa; XWindowAttributes attribs; unsigned long xswamask; int depth; + struct xvctx *ctx = vo->priv; + int i; -#ifdef CONFIG_XF86VM - int vm = flags & VOFLAG_MODESWITCHING; -#endif - - image_height = height; - image_width = width; - image_format = format; + ctx->image_height = height; + ctx->image_width = width; + ctx->image_format = format; - if ((max_width != 0 && max_height != 0) && - (image_width > max_width || image_height > max_height)) - { - mp_msg( MSGT_VO, MSGL_ERR, MSGTR_VO_XV_ImagedimTooHigh, - image_width, image_height, max_width, max_height); + if ((ctx->max_width != 0 && ctx->max_height != 0) + && (ctx->image_width > ctx->max_width + || ctx->image_height > ctx->max_height)) { + mp_msg(MSGT_VO, MSGL_ERR, MSGTR_VO_XV_ImagedimTooHigh, + ctx->image_width, ctx->image_height, ctx->max_width, + ctx->max_height); return -1; } - int_pause = 0; - visible_buf = -1; - - num_buffers = - vo_doublebuffering ? (vo_directrendering ? NUM_BUFFERS : 2) : 1; + ctx->is_paused = 0; + ctx->visible_buf = -1; + ctx->have_visible_image_copy = false; + ctx->have_next_image_copy = false; /* check image formats */ - { - unsigned int i; - - xv_format = 0; - for (i = 0; i < formats; i++) - { - mp_msg(MSGT_VO, MSGL_V, - "Xvideo image format: 0x%x (%4.4s) %s\n", fo[i].id, - (char *) &fo[i].id, - (fo[i].format == XvPacked) ? "packed" : "planar"); - if (fo[i].id == format) - xv_format = fo[i].id; - } - if (!xv_format) - return -1; + ctx->xv_format = 0; + for (i = 0; i < ctx->formats; i++) { + mp_msg(MSGT_VO, MSGL_V, "Xvideo image format: 0x%x (%4.4s) %s\n", + ctx->fo[i].id, (char *) &ctx->fo[i].id, + (ctx->fo[i].format == XvPacked) ? "packed" : "planar"); + if (ctx->fo[i].id == format) + ctx->xv_format = ctx->fo[i].id; } + if (!ctx->xv_format) + return -1; #ifdef CONFIG_GUI if (use_gui) @@ -227,580 +247,621 @@ static int config(uint32_t width, uint32_t height, uint32_t d_width, #endif { #ifdef CONFIG_XF86VM - if (vm) - { - vo_vm_switch(); + int vm = flags & VOFLAG_MODESWITCHING; + if (vm) { + vo_vm_switch(vo); + ctx->mode_switched = 1; } #endif - XGetWindowAttributes(mDisplay, DefaultRootWindow(mDisplay), + XGetWindowAttributes(x11->display, DefaultRootWindow(x11->display), &attribs); depth = attribs.depth; if (depth != 15 && depth != 16 && depth != 24 && depth != 32) depth = 24; - XMatchVisualInfo(mDisplay, mScreen, depth, TrueColor, &vinfo); + XMatchVisualInfo(x11->display, x11->screen, depth, TrueColor, &vinfo); xswa.background_pixel = 0; - if (xv_ck_info.method == CK_METHOD_BACKGROUND) - { - xswa.background_pixel = xv_colorkey; - } + if (x11->xv_ck_info.method == CK_METHOD_BACKGROUND) + xswa.background_pixel = x11->xv_colorkey; xswa.border_pixel = 0; xswamask = CWBackPixel | CWBorderPixel; - vo_x11_create_vo_window(&vinfo, vo_dx, vo_dy, vo_dwidth, vo_dheight, - flags, CopyFromParent, "xv", title); - XChangeWindowAttributes(mDisplay, vo_window, xswamask, &xswa); + vo_x11_create_vo_window(vo, &vinfo, vo->dx, vo->dy, vo->dwidth, + vo->dheight, flags, CopyFromParent, "xv", + title); + XChangeWindowAttributes(x11->display, x11->window, xswamask, &xswa); #ifdef CONFIG_XF86VM - if (vm) - { + if (vm) { /* Grab the mouse pointer in our window */ if (vo_grabpointer) - XGrabPointer(mDisplay, vo_window, True, 0, - GrabModeAsync, GrabModeAsync, - vo_window, None, CurrentTime); - XSetInputFocus(mDisplay, vo_window, RevertToNone, CurrentTime); + XGrabPointer(x11->display, x11->window, True, 0, GrabModeAsync, + GrabModeAsync, x11->window, None, CurrentTime); + XSetInputFocus(x11->display, x11->window, RevertToNone, + CurrentTime); } #endif } mp_msg(MSGT_VO, MSGL_V, "using Xvideo port %d for hw scaling\n", - xv_port); - - switch (xv_format) - { - case IMGFMT_YV12: - case IMGFMT_I420: - case IMGFMT_IYUV: - draw_alpha_fnc = draw_alpha_yv12; - break; - case IMGFMT_YUY2: - case IMGFMT_YVYU: - draw_alpha_fnc = draw_alpha_yuy2; - break; - case IMGFMT_UYVY: - draw_alpha_fnc = draw_alpha_uyvy; - break; - default: - draw_alpha_fnc = draw_alpha_null; + x11->xv_port); + + switch (ctx->xv_format) { + case IMGFMT_YV12: + case IMGFMT_I420: + case IMGFMT_IYUV: + ctx->draw_alpha_fnc = draw_alpha_yv12; + break; + case IMGFMT_YUY2: + case IMGFMT_YVYU: + ctx->draw_alpha_fnc = draw_alpha_yuy2; + break; + case IMGFMT_UYVY: + ctx->draw_alpha_fnc = draw_alpha_uyvy; + break; + default: + ctx->draw_alpha_fnc = draw_alpha_null; } - if (vo_config_count) - for (current_buf = 0; current_buf < num_buffers; ++current_buf) - deallocate_xvimage(current_buf); + // In case config has been called before + for (i = 0; i < ctx->total_buffers; i++) + deallocate_xvimage(vo, i); - for (current_buf = 0; current_buf < num_buffers; ++current_buf) - allocate_xvimage(current_buf); + ctx->num_buffers = + vo_doublebuffering ? (vo_directrendering ? NUM_BUFFERS : 2) : 1; + ctx->total_buffers = ctx->num_buffers + 1; + + for (i = 0; i < ctx->total_buffers; i++) + allocate_xvimage(vo, i); - current_buf = 0; - current_ip_buf = 0; + ctx->current_buf = 0; + ctx->current_ip_buf = 0; - if ((flags & VOFLAG_FULLSCREEN) && WinID <= 0) vo_fs = 1; - - resize(); + if ((flags & VOFLAG_FULLSCREEN) && WinID <= 0) + vo_fs = 1; + + resize(vo); return 0; } -static void allocate_xvimage(int foo) +static void allocate_xvimage(struct vo *vo, int foo) { + struct xvctx *ctx = vo->priv; + struct vo_x11_state *x11 = vo->x11; /* * allocate XvImages. FIXME: no error checking, without * mit-shm this will bomb... trzing to fix ::atmos */ #ifdef HAVE_SHM - if (mLocalDisplay && XShmQueryExtension(mDisplay)) - Shmem_Flag = 1; - else - { - Shmem_Flag = 0; - mp_msg(MSGT_VO, MSGL_INFO, - MSGTR_LIBVO_XV_SharedMemoryNotSupported); + if (x11->display_is_local && XShmQueryExtension(x11->display)) + ctx->Shmem_Flag = 1; + else { + ctx->Shmem_Flag = 0; + mp_msg(MSGT_VO, MSGL_INFO, MSGTR_LIBVO_XV_SharedMemoryNotSupported); } - if (Shmem_Flag) - { - xvimage[foo] = - (XvImage *) XvShmCreateImage(mDisplay, xv_port, xv_format, - NULL, image_width, image_height, - &Shminfo[foo]); - - Shminfo[foo].shmid = - shmget(IPC_PRIVATE, xvimage[foo]->data_size, IPC_CREAT | 0777); - Shminfo[foo].shmaddr = (char *) shmat(Shminfo[foo].shmid, 0, 0); - Shminfo[foo].readOnly = False; - - xvimage[foo]->data = Shminfo[foo].shmaddr; - XShmAttach(mDisplay, &Shminfo[foo]); - XSync(mDisplay, False); - shmctl(Shminfo[foo].shmid, IPC_RMID, 0); + if (ctx->Shmem_Flag) { + ctx->xvimage[foo] = + (XvImage *) XvShmCreateImage(x11->display, x11->xv_port, + ctx->xv_format, NULL, + ctx->image_width, ctx->image_height, + &ctx->Shminfo[foo]); + + ctx->Shminfo[foo].shmid = shmget(IPC_PRIVATE, + ctx->xvimage[foo]->data_size, + IPC_CREAT | 0777); + ctx->Shminfo[foo].shmaddr = (char *) shmat(ctx->Shminfo[foo].shmid, 0, + 0); + ctx->Shminfo[foo].readOnly = False; + + ctx->xvimage[foo]->data = ctx->Shminfo[foo].shmaddr; + XShmAttach(x11->display, &ctx->Shminfo[foo]); + XSync(x11->display, False); + shmctl(ctx->Shminfo[foo].shmid, IPC_RMID, 0); } else #endif { - xvimage[foo] = - (XvImage *) XvCreateImage(mDisplay, xv_port, xv_format, NULL, - image_width, image_height); - xvimage[foo]->data = malloc(xvimage[foo]->data_size); - XSync(mDisplay, False); + ctx->xvimage[foo] = + (XvImage *) XvCreateImage(x11->display, x11->xv_port, + ctx->xv_format, NULL, ctx->image_width, + ctx->image_height); + ctx->xvimage[foo]->data = malloc(ctx->xvimage[foo]->data_size); + XSync(x11->display, False); } - memset(xvimage[foo]->data, 128, xvimage[foo]->data_size); + memset(ctx->xvimage[foo]->data, 128, ctx->xvimage[foo]->data_size); return; } -static void deallocate_xvimage(int foo) +static void deallocate_xvimage(struct vo *vo, int foo) { + struct xvctx *ctx = vo->priv; #ifdef HAVE_SHM - if (Shmem_Flag) - { - XShmDetach(mDisplay, &Shminfo[foo]); - shmdt(Shminfo[foo].shmaddr); + if (ctx->Shmem_Flag) { + XShmDetach(vo->x11->display, &ctx->Shminfo[foo]); + shmdt(ctx->Shminfo[foo].shmaddr); } else #endif { - free(xvimage[foo]->data); + free(ctx->xvimage[foo]->data); } - XFree(xvimage[foo]); + XFree(ctx->xvimage[foo]); - XSync(mDisplay, False); + XSync(vo->x11->display, False); return; } -static inline void put_xvimage( XvImage * xvi ) +static inline void put_xvimage(struct vo *vo, XvImage *xvi) { + struct xvctx *ctx = vo->priv; + struct vo_x11_state *x11 = vo->x11; + struct vo_rect *src = &ctx->src_rect; + struct vo_rect *dst = &ctx->dst_rect; #ifdef HAVE_SHM - if (Shmem_Flag) - { - XvShmPutImage(mDisplay, xv_port, vo_window, vo_gc, - xvi, - src_rect.left, src_rect.top, src_rect.width, src_rect.height, - dst_rect.left, dst_rect.top, dst_rect.width, dst_rect.height, + if (ctx->Shmem_Flag) { + XvShmPutImage(x11->display, x11->xv_port, x11->window, x11->vo_gc, xvi, + src->left, src->top, src->width, src->height, + dst->left, dst->top, dst->width, dst->height, False); } else #endif { - XvPutImage(mDisplay, xv_port, vo_window, vo_gc, - xvi, - src_rect.left, src_rect.top, src_rect.width, src_rect.height, - dst_rect.left, dst_rect.top, dst_rect.width, dst_rect.height); + XvPutImage(x11->display, x11->xv_port, x11->window, x11->vo_gc, xvi, + src->left, src->top, src->width, src->height, + dst->left, dst->top, dst->width, dst->height); } } -static void check_events(void) +// Only copies luma for planar formats as draw_alpha doesn't change others */ +void copy_backup_image(struct vo *vo, int dest, int src) { - int e = vo_x11_check_events(mDisplay); + struct xvctx *ctx = vo->priv; + + XvImage *vb = ctx->xvimage[dest]; + XvImage *cp = ctx->xvimage[src]; + memcpy_pic(vb->data + vb->offsets[0], cp->data + cp->offsets[0], + vb->width, vb->height, + vb->pitches[0], cp->pitches[0]); +} + +static void check_events(struct vo *vo) +{ + struct xvctx *ctx = vo->priv; + struct vo_x11_state *x11 = vo->x11; + int e = vo_x11_check_events(vo); if (e & VO_EVENT_EXPOSE || e & VO_EVENT_RESIZE) - { - resize(); - } + resize(vo); - if ((e & VO_EVENT_EXPOSE || e & VO_EVENT_RESIZE) && int_pause) - { + if ((e & VO_EVENT_EXPOSE || e & VO_EVENT_RESIZE) && ctx->is_paused) { /* did we already draw a buffer */ - if ( visible_buf != -1 ) - { - /* redraw the last visible buffer */ - put_xvimage( xvimage[visible_buf] ); + if (ctx->visible_buf != -1) { + /* redraw the last visible buffer */ + put_xvimage(vo, ctx->xvimage[ctx->visible_buf]); } } } -static void draw_osd(void) +static void draw_osd(struct vo *vo, struct osd_state *osd) { - vo_draw_text(image_width - - image_width * vo_panscan_x / (vo_dwidth + vo_panscan_x), - image_height, draw_alpha_fnc); + struct xvctx *ctx = vo->priv; + + ctx->osd_objects_drawn = 0; + osd_draw_text(osd, + ctx->image_width - + ctx->image_width * vo->panscan_x / (vo->dwidth + + vo->panscan_x), + ctx->image_height, ctx->draw_alpha_fnc, vo); + if (ctx->osd_objects_drawn) + ctx->unchanged_next_image = false; +} + +static int redraw_osd(struct vo *vo, struct osd_state *osd) +{ + struct xvctx *ctx = vo->priv; + + if (ctx->have_visible_image_copy) + copy_backup_image(vo, ctx->visible_buf, ctx->num_buffers); + else if (ctx->unchanged_visible_image) { + copy_backup_image(vo, ctx->num_buffers, ctx->visible_buf); + ctx->have_visible_image_copy = true; + } + else + return false; + int temp = ctx->current_buf; + ctx->current_buf = ctx->visible_buf; + draw_osd(vo, osd); + ctx->current_buf = temp; + put_xvimage(vo, ctx->xvimage[ctx->visible_buf]); + return true; } -static void flip_page(void) +static void flip_page(struct vo *vo) { - put_xvimage( xvimage[current_buf] ); + struct xvctx *ctx = vo->priv; + put_xvimage(vo, ctx->xvimage[ctx->current_buf]); /* remember the currently visible buffer */ - visible_buf = current_buf; + ctx->visible_buf = ctx->current_buf; - if (num_buffers > 1) - { - current_buf = - vo_directrendering ? 0 : ((current_buf + 1) % num_buffers); - XFlush(mDisplay); + ctx->have_visible_image_copy = ctx->have_next_image_copy; + ctx->have_next_image_copy = false; + ctx->unchanged_visible_image = ctx->unchanged_next_image; + ctx->unchanged_next_image = false; + + if (ctx->num_buffers > 1) { + ctx->current_buf = vo_directrendering ? 0 : ((ctx->current_buf + 1) % + ctx->num_buffers); + XFlush(vo->x11->display); } else - XSync(mDisplay, False); + XSync(vo->x11->display, False); return; } -static int draw_slice(uint8_t * image[], int stride[], int w, int h, - int x, int y) +static int draw_slice(struct vo *vo, uint8_t *image[], int stride[], int w, + int h, int x, int y) { + struct xvctx *ctx = vo->priv; uint8_t *dst; + XvImage *current_image = ctx->xvimage[ctx->current_buf]; - dst = xvimage[current_buf]->data + xvimage[current_buf]->offsets[0] + - xvimage[current_buf]->pitches[0] * y + x; - memcpy_pic(dst, image[0], w, h, xvimage[current_buf]->pitches[0], - stride[0]); + dst = current_image->data + current_image->offsets[0] + + current_image->pitches[0] * y + x; + memcpy_pic(dst, image[0], w, h, current_image->pitches[0], stride[0]); x /= 2; y /= 2; w /= 2; h /= 2; - dst = xvimage[current_buf]->data + xvimage[current_buf]->offsets[1] + - xvimage[current_buf]->pitches[1] * y + x; - if (image_format != IMGFMT_YV12) - memcpy_pic(dst, image[1], w, h, xvimage[current_buf]->pitches[1], - stride[1]); + dst = current_image->data + current_image->offsets[1] + + current_image->pitches[1] * y + x; + if (ctx->image_format != IMGFMT_YV12) + memcpy_pic(dst, image[1], w, h, current_image->pitches[1], stride[1]); else - memcpy_pic(dst, image[2], w, h, xvimage[current_buf]->pitches[1], - stride[2]); - - dst = xvimage[current_buf]->data + xvimage[current_buf]->offsets[2] + - xvimage[current_buf]->pitches[2] * y + x; - if (image_format == IMGFMT_YV12) - memcpy_pic(dst, image[1], w, h, xvimage[current_buf]->pitches[1], - stride[1]); + memcpy_pic(dst, image[2], w, h, current_image->pitches[1], stride[2]); + + dst = current_image->data + current_image->offsets[2] + + current_image->pitches[2] * y + x; + if (ctx->image_format == IMGFMT_YV12) + memcpy_pic(dst, image[1], w, h, current_image->pitches[1], stride[1]); else - memcpy_pic(dst, image[2], w, h, xvimage[current_buf]->pitches[1], - stride[2]); + memcpy_pic(dst, image[2], w, h, current_image->pitches[1], stride[2]); return 0; } -static int draw_frame(uint8_t * src[]) +static int draw_frame(struct vo *vo, uint8_t *src[]) { return VO_ERROR; } -static uint32_t draw_image(mp_image_t * mpi) +static uint32_t draw_image(struct vo *vo, mp_image_t *mpi) { + struct xvctx *ctx = vo->priv; + + ctx->have_next_image_copy = false; + if (mpi->flags & MP_IMGFLAG_DIRECT) - { // direct rendering: - current_buf = (int) (mpi->priv); // hack! - return VO_TRUE; - } - if (mpi->flags & MP_IMGFLAG_DRAW_CALLBACK) - return VO_TRUE; // done - if (mpi->flags & MP_IMGFLAG_PLANAR) - { - draw_slice(mpi->planes, mpi->stride, mpi->w, mpi->h, 0, 0); - return VO_TRUE; - } - if (mpi->flags & MP_IMGFLAG_YUV) - { + ctx->current_buf = (int) (mpi->priv); // hack! + else if (mpi->flags & MP_IMGFLAG_DRAW_CALLBACK) + ; // done + else if (mpi->flags & MP_IMGFLAG_PLANAR) + draw_slice(vo, mpi->planes, mpi->stride, mpi->w, mpi->h, 0, 0); + else if (mpi->flags & MP_IMGFLAG_YUV) // packed YUV: - memcpy_pic(xvimage[current_buf]->data + - xvimage[current_buf]->offsets[0], mpi->planes[0], + memcpy_pic(ctx->xvimage[ctx->current_buf]->data + + ctx->xvimage[ctx->current_buf]->offsets[0], mpi->planes[0], mpi->w * (mpi->bpp / 8), mpi->h, - xvimage[current_buf]->pitches[0], mpi->stride[0]); - return VO_TRUE; + ctx->xvimage[ctx->current_buf]->pitches[0], mpi->stride[0]); + else + return false; + + if (ctx->is_paused) { + copy_backup_image(vo, ctx->num_buffers, ctx->current_buf); + ctx->have_next_image_copy = true; } - return VO_FALSE; // not (yet) supported + ctx->unchanged_next_image = true; + return true; } -static uint32_t get_image(mp_image_t * mpi) +static uint32_t get_image(struct xvctx *ctx, mp_image_t *mpi) { - int buf = current_buf; // we shouldn't change current_buf unless we do DR! + // we shouldn't change current_buf unless we do DR! + int buf = ctx->current_buf; - if (mpi->type == MP_IMGTYPE_STATIC && num_buffers > 1) + if (mpi->type == MP_IMGTYPE_STATIC && ctx->num_buffers > 1) return VO_FALSE; // it is not static - if (mpi->imgfmt != image_format) + if (mpi->imgfmt != ctx->image_format) return VO_FALSE; // needs conversion :( -// if(mpi->flags&MP_IMGFLAG_READABLE) return VO_FALSE; // slow video ram - if (mpi->flags & MP_IMGFLAG_READABLE && - (mpi->type == MP_IMGTYPE_IPB || mpi->type == MP_IMGTYPE_IP)) - { + if (mpi->flags & MP_IMGFLAG_READABLE + && (mpi->type == MP_IMGTYPE_IPB || mpi->type == MP_IMGTYPE_IP)) { // reference (I/P) frame of IP or IPB: - if (num_buffers < 2) + if (ctx->num_buffers < 2) return VO_FALSE; // not enough - current_ip_buf ^= 1; + ctx->current_ip_buf ^= 1; // for IPB with 2 buffers we can DR only one of the 2 P frames: - if (mpi->type == MP_IMGTYPE_IPB && num_buffers < 3 - && current_ip_buf) + if (mpi->type == MP_IMGTYPE_IPB && ctx->num_buffers < 3 + && ctx->current_ip_buf) return VO_FALSE; - buf = current_ip_buf; + buf = ctx->current_ip_buf; if (mpi->type == MP_IMGTYPE_IPB) ++buf; // preserve space for B } - if (mpi->height > xvimage[buf]->height) + if (mpi->height > ctx->xvimage[buf]->height) return VO_FALSE; //buffer to small - if (mpi->width * (mpi->bpp / 8) > xvimage[buf]->pitches[0]) + if (mpi->width * (mpi->bpp / 8) > ctx->xvimage[buf]->pitches[0]) return VO_FALSE; //buffer to small if ((mpi->flags & (MP_IMGFLAG_ACCEPT_STRIDE | MP_IMGFLAG_ACCEPT_WIDTH)) - || (mpi->width * (mpi->bpp / 8) == xvimage[buf]->pitches[0])) - { - current_buf = buf; - mpi->planes[0] = - xvimage[current_buf]->data + xvimage[current_buf]->offsets[0]; - mpi->stride[0] = xvimage[current_buf]->pitches[0]; + || (mpi->width * (mpi->bpp / 8) == ctx->xvimage[buf]->pitches[0])) { + ctx->current_buf = buf; + XvImage *current_image = ctx->xvimage[ctx->current_buf]; + mpi->planes[0] = current_image->data + current_image->offsets[0]; + mpi->stride[0] = current_image->pitches[0]; mpi->width = mpi->stride[0] / (mpi->bpp / 8); - if (mpi->flags & MP_IMGFLAG_PLANAR) - { - if (mpi->flags & MP_IMGFLAG_SWAPPED) - { + if (mpi->flags & MP_IMGFLAG_PLANAR) { + if (mpi->flags & MP_IMGFLAG_SWAPPED) { // I420 - mpi->planes[1] = - xvimage[current_buf]->data + - xvimage[current_buf]->offsets[1]; - mpi->planes[2] = - xvimage[current_buf]->data + - xvimage[current_buf]->offsets[2]; - mpi->stride[1] = xvimage[current_buf]->pitches[1]; - mpi->stride[2] = xvimage[current_buf]->pitches[2]; - } else - { + mpi->planes[1] = current_image->data + + current_image->offsets[1]; + mpi->planes[2] = current_image->data + + current_image->offsets[2]; + mpi->stride[1] = current_image->pitches[1]; + mpi->stride[2] = current_image->pitches[2]; + } else { // YV12 - mpi->planes[1] = - xvimage[current_buf]->data + - xvimage[current_buf]->offsets[2]; - mpi->planes[2] = - xvimage[current_buf]->data + - xvimage[current_buf]->offsets[1]; - mpi->stride[1] = xvimage[current_buf]->pitches[2]; - mpi->stride[2] = xvimage[current_buf]->pitches[1]; + mpi->planes[1] = current_image->data + + current_image->offsets[2]; + mpi->planes[2] = current_image->data + + current_image->offsets[1]; + mpi->stride[1] = current_image->pitches[2]; + mpi->stride[2] = current_image->pitches[1]; } } mpi->flags |= MP_IMGFLAG_DIRECT; - mpi->priv = (void *) current_buf; -// printf("mga: get_image() SUCCESS -> Direct Rendering ENABLED\n"); + mpi->priv = (void *) ctx->current_buf; return VO_TRUE; } return VO_FALSE; } -static int query_format(uint32_t format) +static int query_format(struct xvctx *ctx, uint32_t format) { uint32_t i; int flag = VFCAP_CSP_SUPPORTED | VFCAP_CSP_SUPPORTED_BY_HW | VFCAP_HWSCALE_UP | VFCAP_HWSCALE_DOWN | VFCAP_OSD | VFCAP_ACCEPT_STRIDE; // FIXME! check for DOWN /* check image formats */ - for (i = 0; i < formats; i++) - { - if (fo[i].id == format) + for (i = 0; i < ctx->formats; i++) { + if (ctx->fo[i].id == format) return flag; //xv_format = fo[i].id; } return 0; } -static void uninit(void) +static void uninit(struct vo *vo) { + struct xvctx *ctx = vo->priv; int i; - if (!vo_config_count) - return; - visible_buf = -1; - XvFreeAdaptorInfo(ai); - ai = NULL; - if(fo){ - XFree(fo); - fo=NULL; + ctx->visible_buf = -1; + if (ctx->ai) + XvFreeAdaptorInfo(ctx->ai); + ctx->ai = NULL; + if (ctx->fo) { + XFree(ctx->fo); + ctx->fo = NULL; } - for (i = 0; i < num_buffers; i++) - deallocate_xvimage(i); + for (i = 0; i < ctx->total_buffers; i++) + deallocate_xvimage(vo, i); #ifdef CONFIG_XF86VM - vo_vm_close(); + if (ctx->mode_switched) + vo_vm_close(vo); #endif - mp_input_rm_event_fd(ConnectionNumber(mDisplay)); - vo_x11_uninit(); + if (ctx->event_fd_registered) + mp_input_rm_key_fd(vo->input_ctx, ConnectionNumber(vo->x11->display)); + // uninit() shouldn't get called unless initialization went past vo_init() + vo_x11_uninit(vo); +} + +static int x11_fd_callback(void *ctx, int fd) +{ + struct vo *vo = ctx; + check_events(vo); + return mplayer_get_key(vo->key_fifo, 0); } -static int preinit(const char *arg) +static int preinit(struct vo *vo, const char *arg) { XvPortID xv_p; int busy_ports = 0; unsigned int i; strarg_t ck_src_arg = { 0, NULL }; strarg_t ck_method_arg = { 0, NULL }; + struct xvctx *ctx = talloc_zero(vo, struct xvctx); + vo->priv = ctx; + struct vo_x11_state *x11 = vo->x11; int xv_adaptor = -1; - opt_t subopts[] = - { - /* name arg type arg var test */ - { "port", OPT_ARG_INT, &xv_port, (opt_test_f)int_pos }, - { "adaptor", OPT_ARG_INT, &xv_adaptor, (opt_test_f)int_non_neg }, - { "ck", OPT_ARG_STR, &ck_src_arg, xv_test_ck }, - { "ck-method", OPT_ARG_STR, &ck_method_arg, xv_test_ckm }, - { NULL } + opt_t subopts[] = { + /* name arg type arg var test */ + {"port", OPT_ARG_INT, &x11->xv_port, (opt_test_f) int_pos}, + {"adaptor", OPT_ARG_INT, &xv_adaptor, (opt_test_f) int_non_neg}, + {"ck", OPT_ARG_STR, &ck_src_arg, xv_test_ck}, + {"ck-method", OPT_ARG_STR, &ck_method_arg, xv_test_ckm}, + {NULL} }; - xv_port = 0; + x11->xv_port = 0; /* parse suboptions */ - if ( subopt_parse( arg, subopts ) != 0 ) - { - return -1; + if (subopt_parse(arg, subopts) != 0) { + return -1; } /* modify colorkey settings according to the given options */ - xv_setup_colorkeyhandling( ck_method_arg.str, ck_src_arg.str ); + xv_setup_colorkeyhandling(vo, ck_method_arg.str, ck_src_arg.str); - if (!vo_init()) + if (!vo_init(vo)) return -1; /* check for Xvideo extension */ - if (Success != XvQueryExtension(mDisplay, &ver, &rel, &req, &ev, &err)) - { - mp_msg(MSGT_VO, MSGL_ERR, - MSGTR_LIBVO_XV_XvNotSupportedByX11); - return -1; + unsigned int ver, rel, req, ev, err; + if (Success != XvQueryExtension(x11->display, &ver, &rel, &req, &ev, &err)) { + mp_msg(MSGT_VO, MSGL_ERR, MSGTR_LIBVO_XV_XvNotSupportedByX11); + goto error; } /* check for Xvideo support */ if (Success != - XvQueryAdaptors(mDisplay, DefaultRootWindow(mDisplay), &adaptors, - &ai)) - { + XvQueryAdaptors(x11->display, DefaultRootWindow(x11->display), + &ctx->adaptors, &ctx->ai)) { mp_msg(MSGT_VO, MSGL_ERR, MSGTR_LIBVO_XV_XvQueryAdaptorsFailed); - return -1; + goto error; } /* check adaptors */ - if (xv_port) - { + if (x11->xv_port) { int port_found; - for (port_found = 0, i = 0; !port_found && i < adaptors; i++) - { - if ((ai[i].type & XvInputMask) && (ai[i].type & XvImageMask)) - { - for (xv_p = ai[i].base_id; - xv_p < ai[i].base_id + ai[i].num_ports; ++xv_p) - { - if (xv_p == xv_port) - { + for (port_found = 0, i = 0; !port_found && i < ctx->adaptors; i++) { + if ((ctx->ai[i].type & XvInputMask) + && (ctx->ai[i].type & XvImageMask)) { + for (xv_p = ctx->ai[i].base_id; + xv_p < ctx->ai[i].base_id + ctx->ai[i].num_ports; + ++xv_p) { + if (xv_p == x11->xv_port) { port_found = 1; break; } } } } - if (port_found) - { - if (XvGrabPort(mDisplay, xv_port, CurrentTime)) - xv_port = 0; - } else - { - mp_msg(MSGT_VO, MSGL_WARN, - MSGTR_LIBVO_XV_InvalidPortParameter); - xv_port = 0; + if (port_found) { + if (XvGrabPort(x11->display, x11->xv_port, CurrentTime)) + x11->xv_port = 0; + } else { + mp_msg(MSGT_VO, MSGL_WARN, MSGTR_LIBVO_XV_InvalidPortParameter); + x11->xv_port = 0; } } - for (i = 0; i < adaptors && xv_port == 0; i++) - { + for (i = 0; i < ctx->adaptors && x11->xv_port == 0; i++) { /* check if adaptor number has been specified */ if (xv_adaptor != -1 && xv_adaptor != i) - continue; - - if ((ai[i].type & XvInputMask) && (ai[i].type & XvImageMask)) - { - for (xv_p = ai[i].base_id; - xv_p < ai[i].base_id + ai[i].num_ports; ++xv_p) - if (!XvGrabPort(mDisplay, xv_p, CurrentTime)) - { - xv_port = xv_p; + continue; + + if ((ctx->ai[i].type & XvInputMask) && (ctx->ai[i].type & XvImageMask)) { + for (xv_p = ctx->ai[i].base_id; + xv_p < ctx->ai[i].base_id + ctx->ai[i].num_ports; ++xv_p) + if (!XvGrabPort(x11->display, xv_p, CurrentTime)) { + x11->xv_port = xv_p; mp_msg(MSGT_VO, MSGL_V, "[VO_XV] Using Xv Adapter #%d (%s)\n", - i, ai[i].name); + i, ctx->ai[i].name); break; - } else - { - mp_msg(MSGT_VO, MSGL_WARN, - MSGTR_LIBVO_XV_CouldNotGrabPort, (int) xv_p); + } else { + mp_msg(MSGT_VO, MSGL_WARN, MSGTR_LIBVO_XV_CouldNotGrabPort, + (int) xv_p); ++busy_ports; } } } - if (!xv_port) - { + if (!x11->xv_port) { if (busy_ports) - mp_msg(MSGT_VO, MSGL_ERR, - MSGTR_LIBVO_XV_CouldNotFindFreePort); + mp_msg(MSGT_VO, MSGL_ERR, MSGTR_LIBVO_XV_CouldNotFindFreePort); else - mp_msg(MSGT_VO, MSGL_ERR, - MSGTR_LIBVO_XV_NoXvideoSupport); - return -1; + mp_msg(MSGT_VO, MSGL_ERR, MSGTR_LIBVO_XV_NoXvideoSupport); + goto error; } - if ( !vo_xv_init_colorkey() ) - { - return -1; // bail out, colorkey setup failed + if (!vo_xv_init_colorkey(vo)) { + goto error; // bail out, colorkey setup failed } - vo_xv_enable_vsync(); - vo_xv_get_max_img_dim( &max_width, &max_height ); + vo_xv_enable_vsync(vo); + vo_xv_get_max_img_dim(vo, &ctx->max_width, &ctx->max_height); - fo = XvListImageFormats(mDisplay, xv_port, (int *) &formats); + ctx->fo = XvListImageFormats(x11->display, x11->xv_port, + (int *) &ctx->formats); - mp_input_add_event_fd(ConnectionNumber(mDisplay), check_events); + mp_input_add_key_fd(vo->input_ctx, ConnectionNumber(x11->display), 1, + x11_fd_callback, NULL, vo); + ctx->event_fd_registered = 1; return 0; + + error: + uninit(vo); // free resources + return -1; } -static int control(uint32_t request, void *data, ...) +static int control(struct vo *vo, uint32_t request, void *data) { - switch (request) - { - case VOCTRL_PAUSE: - return int_pause = 1; - case VOCTRL_RESUME: - return int_pause = 0; - case VOCTRL_QUERY_FORMAT: - return query_format(*((uint32_t *) data)); - case VOCTRL_GET_IMAGE: - return get_image(data); - case VOCTRL_DRAW_IMAGE: - return draw_image(data); - case VOCTRL_GUISUPPORT: - return VO_TRUE; - case VOCTRL_GET_PANSCAN: - if (!vo_config_count || !vo_fs) - return VO_FALSE; - return VO_TRUE; - case VOCTRL_FULLSCREEN: - vo_x11_fullscreen(); - /* indended, fallthrough to update panscan on fullscreen/windowed switch */ - case VOCTRL_SET_PANSCAN: - if ((vo_fs && (vo_panscan != vo_panscan_amount)) - || (!vo_fs && vo_panscan_amount)) - { - int old_y = vo_panscan_y; - - panscan_calc(); - - if (old_y != vo_panscan_y) - { - resize(); - flip_page(); - } - } - return VO_TRUE; - case VOCTRL_SET_EQUALIZER: - { - va_list ap; - int value; - - va_start(ap, data); - value = va_arg(ap, int); - - va_end(ap); - - return vo_xv_set_eq(xv_port, data, value); - } - case VOCTRL_GET_EQUALIZER: - { - va_list ap; - int *value; - - va_start(ap, data); - value = va_arg(ap, int *); - - va_end(ap); - - return vo_xv_get_eq(xv_port, data, value); + struct xvctx *ctx = vo->priv; + struct vo_x11_state *x11 = vo->x11; + switch (request) { + case VOCTRL_PAUSE: + return (ctx->is_paused = 1); + case VOCTRL_RESUME: + return (ctx->is_paused = 0); + case VOCTRL_QUERY_FORMAT: + return query_format(ctx, *((uint32_t *) data)); + case VOCTRL_GET_IMAGE: + return get_image(ctx, data); + case VOCTRL_DRAW_IMAGE: + return draw_image(vo, data); + case VOCTRL_GUISUPPORT: + return VO_TRUE; + case VOCTRL_GET_PANSCAN: + if (!vo->config_ok || !vo_fs) + return VO_FALSE; + return VO_TRUE; + case VOCTRL_FULLSCREEN: + vo_x11_fullscreen(vo); + /* indended, fallthrough to update panscan on fullscreen/windowed switch */ + case VOCTRL_SET_PANSCAN: + if ((vo_fs && (vo_panscan != vo->panscan_amount)) + || (!vo_fs && vo->panscan_amount)) { + int old_y = vo->panscan_y; + + panscan_calc(vo); + + if (old_y != vo->panscan_y) { + resize(vo); + flip_page(vo); } - case VOCTRL_ONTOP: - vo_x11_ontop(); - return VO_TRUE; - case VOCTRL_UPDATE_SCREENINFO: - update_xinerama_info(); - return VO_TRUE; + } + return VO_TRUE; + case VOCTRL_SET_EQUALIZER: + { + struct voctrl_set_equalizer_args *args = data; + return vo_xv_set_eq(vo, x11->xv_port, args->name, args->value); + } + case VOCTRL_GET_EQUALIZER: + { + struct voctrl_get_equalizer_args *args = data; + return vo_xv_get_eq(vo, x11->xv_port, args->name, args->valueptr); + } + case VOCTRL_ONTOP: + vo_x11_ontop(vo); + return VO_TRUE; + case VOCTRL_UPDATE_SCREENINFO: + update_xinerama_info(vo); + return VO_TRUE; + case VOCTRL_REDRAW_OSD: + return redraw_osd(vo, data); } return VO_NOTIMPL; } + +const struct vo_driver video_out_xv = { + .is_new = 1, + .info = &info, + .preinit = preinit, + .config = config, + .control = control, + .draw_frame = draw_frame, + .draw_slice = draw_slice, + .draw_osd = draw_osd, + .flip_page = flip_page, + .check_events = check_events, + .uninit = uninit +}; diff --git a/libvo/vo_xvidix.c b/libvo/vo_xvidix.c index b48168e6d5..620d6df3b5 100644 --- a/libvo/vo_xvidix.c +++ b/libvo/vo_xvidix.c @@ -409,13 +409,13 @@ static int preinit(const char *arg) if (!vo_init()) return -1; - if (vidix_preinit(vidix_name, &video_out_xvidix) != 0) + if (vidix_preinit(vidix_name, video_out_xvidix.old_functions) != 0) return 1; return 0; } -static int control(uint32_t request, void *data, ...) +static int control(uint32_t request, void *data) { switch (request) { @@ -439,30 +439,6 @@ static int control(uint32_t request, void *data, ...) set_window(0); } return VO_TRUE; - case VOCTRL_SET_EQUALIZER: - { - va_list ap; - int value; - - va_start(ap, data); - value = va_arg(ap, int); - - va_end(ap); - - return vidix_control(request, data, value); - } - case VOCTRL_GET_EQUALIZER: - { - va_list ap; - int *value; - - va_start(ap, data); - value = va_arg(ap, int *); - - va_end(ap); - - return vidix_control(request, data, value); - } case VOCTRL_UPDATE_SCREENINFO: aspect_save_screenres(vo_screenwidth, vo_screenheight); return VO_TRUE; diff --git a/libvo/vo_xvmc.c b/libvo/vo_xvmc.c index ad18fb3231..709967fb41 100644 --- a/libvo/vo_xvmc.c +++ b/libvo/vo_xvmc.c @@ -1287,7 +1287,7 @@ assert(rndr->next_free_data_block_num == 0); return VO_TRUE; } -static int control(uint32_t request, void *data, ... ) +static int control(uint32_t request, void *data) { switch (request){ case VOCTRL_GET_DEINTERLACE: @@ -1329,26 +1329,14 @@ static int control(uint32_t request, void *data, ... ) return VO_TRUE; case VOCTRL_SET_EQUALIZER: { - va_list ap; - int value; - - va_start(ap, data); - value = va_arg(ap, int); - va_end(ap); - - return vo_xv_set_eq(xv_port, data, value); + struct voctrl_set_equalizer_args *args = data; + return vo_xv_set_eq(xv_port, args->name, args->value); } case VOCTRL_GET_EQUALIZER: { - va_list ap; - int *value; - - va_start(ap, data); - value = va_arg(ap, int*); - va_end(ap); - - return vo_xv_get_eq(xv_port, data, value); + struct voctrl_get_equalizer_args *args = data; + return vo_xv_get_eq(xv_port, args->name, args->valueptr); } case VOCTRL_UPDATE_SCREENINFO: update_xinerama_info(); diff --git a/libvo/vo_xvr100.c b/libvo/vo_xvr100.c index 476744729c..7a82c436fb 100644 --- a/libvo/vo_xvr100.c +++ b/libvo/vo_xvr100.c @@ -428,7 +428,7 @@ static int query_format(uint32_t format) return 0; } -static int control(uint32_t request, void *data, ...) +static int control(uint32_t request, void *data) { switch (request) { case VOCTRL_GET_IMAGE: diff --git a/libvo/vo_yuv4mpeg.c b/libvo/vo_yuv4mpeg.c index b983a6ac13..420e7fea91 100644 --- a/libvo/vo_yuv4mpeg.c +++ b/libvo/vo_yuv4mpeg.c @@ -553,7 +553,7 @@ static int preinit(const char *arg) return 0; } -static int control(uint32_t request, void *data, ...) +static int control(uint32_t request, void *data) { switch (request) { case VOCTRL_QUERY_FORMAT: diff --git a/libvo/vo_zr.c b/libvo/vo_zr.c index b73150c3d0..a34744739c 100644 --- a/libvo/vo_zr.c +++ b/libvo/vo_zr.c @@ -830,7 +830,7 @@ static int preinit(const char *arg) return 0; } -static int control(uint32_t request, void *data, ...) +static int control(uint32_t request, void *data) { switch (request) { case VOCTRL_QUERY_FORMAT: diff --git a/libvo/vo_zr2.c b/libvo/vo_zr2.c index fb1fa025e6..d14a8d4d39 100644 --- a/libvo/vo_zr2.c +++ b/libvo/vo_zr2.c @@ -449,7 +449,7 @@ static int config(uint32_t width, uint32_t height, uint32_t d_width, return 0; } -static int control(uint32_t request, void *data, ...) { +static int control(uint32_t request, void *data) { switch (request) { case VOCTRL_QUERY_FORMAT: return query_format(*((uint32_t*)data)); diff --git a/libvo/vosub_vidix.c b/libvo/vosub_vidix.c index 688311b3ab..1c52c31094 100644 --- a/libvo/vosub_vidix.c +++ b/libvo/vosub_vidix.c @@ -44,6 +44,7 @@ #include "video_out.h" #include "sub.h" #include "vosub_vidix.h" +#include "old_vo_wrapper.h" #include "libmpcodecs/vfcap.h" #include "libmpcodecs/mp_image.h" @@ -59,7 +60,7 @@ static int video_on=0; static vidix_capability_t vidix_cap; static vidix_playback_t vidix_play; static vidix_fourcc_t vidix_fourcc; -static vo_functions_t * vo_server; +static struct vo_old_functions *vo_server; static vidix_yuv_t dstrides; /*static uint32_t (*server_control)(uint32_t request, void *data, ...);*/ @@ -96,7 +97,7 @@ void vidix_term( void ) // vo_server->control=server_control; } -static uint32_t vidix_draw_slice_420(uint8_t *image[], int stride[], int w,int h,int x,int y) +static int vidix_draw_slice_420(uint8_t *image[], int stride[], int w,int h,int x,int y) { uint8_t *src; uint8_t *dest; @@ -160,7 +161,7 @@ static uint32_t vidix_draw_slice_420(uint8_t *image[], int stride[], int w,int h return -1; } -static uint32_t vidix_draw_slice_410(uint8_t *image[], int stride[], int w,int h,int x,int y) +static int vidix_draw_slice_410(uint8_t *image[], int stride[], int w,int h,int x,int y) { uint8_t *src; uint8_t *dest; @@ -206,7 +207,7 @@ static uint32_t vidix_draw_slice_410(uint8_t *image[], int stride[], int w,int h return -1; } -static uint32_t vidix_draw_slice_packed(uint8_t *image[], int stride[], int w,int h,int x,int y) +static int vidix_draw_slice_packed(uint8_t *image[], int stride[], int w,int h,int x,int y) { uint8_t *src; uint8_t *dest; @@ -223,7 +224,7 @@ static uint32_t vidix_draw_slice_packed(uint8_t *image[], int stride[], int w,in return 0; } -static uint32_t vidix_draw_slice_nv12(uint8_t *image[], int stride[], int w,int h,int x,int y) +static int vidix_draw_slice_nv12(uint8_t *image[], int stride[], int w,int h,int x,int y) { uint8_t *src; uint8_t *dest; @@ -251,7 +252,7 @@ static uint32_t vidix_draw_slice_nv12(uint8_t *image[], int stride[], int w,int return 0; } -static uint32_t vidix_draw_slice(uint8_t *image[], int stride[], int w,int h,int x,int y) +static int vidix_draw_slice(uint8_t *image[], int stride[], int w,int h,int x,int y) { mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_SUB_VIDIX_DummyVidixdrawsliceWasCalled); return -1; @@ -269,7 +270,7 @@ static uint32_t vidix_draw_image(mp_image_t *mpi){ return VO_TRUE; } -static uint32_t vidix_draw_frame(uint8_t *image[]) +static int vidix_draw_frame(uint8_t *image[]) { mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_SUB_VIDIX_DummyVidixdrawframeWasCalled); return -1; @@ -576,7 +577,7 @@ static uint32_t vidix_get_image(mp_image_t *mpi) return VO_FALSE; } -uint32_t vidix_control(uint32_t request, void *data, ...) +uint32_t vidix_control(uint32_t request, void *data) { switch (request) { case VOCTRL_QUERY_FORMAT: @@ -596,36 +597,31 @@ uint32_t vidix_control(uint32_t request, void *data, ...) return VO_TRUE; case VOCTRL_SET_EQUALIZER: { - va_list ap; - int value; vidix_video_eq_t info; if(!video_on) return VO_FALSE; - va_start(ap, data); - value = va_arg(ap, int); - va_end(ap); - -// printf("vidix seteq %s -> %d \n",data,value); + + struct voctrl_set_equalizer_args *args = data; /* vidix eq ranges are -1000..1000 */ - if (!strcasecmp(data, "brightness")) + if (!strcasecmp(args->name, "brightness")) { - info.brightness = value*10; + info.brightness = args->value*10; info.cap = VEQ_CAP_BRIGHTNESS; } - else if (!strcasecmp(data, "contrast")) + else if (!strcasecmp(args->name, "contrast")) { - info.contrast = value*10; + info.contrast = args->value*10; info.cap = VEQ_CAP_CONTRAST; } - else if (!strcasecmp(data, "saturation")) + else if (!strcasecmp(args->name, "saturation")) { - info.saturation = value*10; + info.saturation = args->value*10; info.cap = VEQ_CAP_SATURATION; } - else if (!strcasecmp(data, "hue")) + else if (!strcasecmp(args->name, "hue")) { - info.hue = value*10; + info.hue = args->value*10; info.cap = VEQ_CAP_HUE; } @@ -635,38 +631,34 @@ uint32_t vidix_control(uint32_t request, void *data, ...) } case VOCTRL_GET_EQUALIZER: { - va_list ap; - int *value; vidix_video_eq_t info; if(!video_on) return VO_FALSE; if (vdlPlaybackGetEq(vidix_handler, &info) != 0) return VO_FALSE; - va_start(ap, data); - value = va_arg(ap, int*); - va_end(ap); + struct voctrl_get_equalizer_args *args = data; /* vidix eq ranges are -1000..1000 */ - if (!strcasecmp(data, "brightness")) + if (!strcasecmp(args->name, "brightness")) { if (info.cap & VEQ_CAP_BRIGHTNESS) - *value = info.brightness/10; + *args->valueptr = info.brightness/10; } - else if (!strcasecmp(data, "contrast")) + else if (!strcasecmp(args->name, "contrast")) { if (info.cap & VEQ_CAP_CONTRAST) - *value = info.contrast/10; + *args->valueptr = info.contrast/10; } - else if (!strcasecmp(data, "saturation")) + else if (!strcasecmp(args->name, "saturation")) { if (info.cap & VEQ_CAP_SATURATION) - *value = info.saturation/10; + *args->valueptr = info.saturation/10; } - else if (!strcasecmp(data, "hue")) + else if (!strcasecmp(args->name, "hue")) { if (info.cap & VEQ_CAP_HUE) - *value = info.hue/10; + *args->valueptr = info.hue/10; } return VO_TRUE; @@ -677,7 +669,7 @@ uint32_t vidix_control(uint32_t request, void *data, ...) // return server_control(request,data); //VO_NOTIMPL; } -int vidix_preinit(const char *drvname,vo_functions_t *server) +int vidix_preinit(const char *drvname, struct vo_old_functions *server) { int err; if( mp_msg_test(MSGT_VO,MSGL_DBG2) ) { diff --git a/libvo/vosub_vidix.h b/libvo/vosub_vidix.h index 128409e95a..7b05607de6 100644 --- a/libvo/vosub_vidix.h +++ b/libvo/vosub_vidix.h @@ -27,7 +27,7 @@ #include "video_out.h" /* drvname can be NULL */ -int vidix_preinit(const char *drvname,vo_functions_t *server); +int vidix_preinit(const char *drvname, struct vo_old_functions *server); int vidix_init(unsigned src_width,unsigned src_height, unsigned dest_x,unsigned dest_y,unsigned dst_width, unsigned dst_height,unsigned format,unsigned dest_bpp, @@ -35,7 +35,7 @@ int vidix_init(unsigned src_width,unsigned src_height, int vidix_start(void); int vidix_stop(void); void vidix_term( void ); -uint32_t vidix_control(uint32_t request, void *data, ...); +uint32_t vidix_control(uint32_t request, void *data); uint32_t vidix_query_fourcc(uint32_t fourcc); #include "vidix/vidix.h" diff --git a/libvo/w32_common.c b/libvo/w32_common.c index 160100db5b..076544dbab 100644 --- a/libvo/w32_common.c +++ b/libvo/w32_common.c @@ -21,6 +21,8 @@ #include <windows.h> #include <windowsx.h> +// To get "#define vo_ontop global_vo->opts->vo_ontop" etc +#include "old_vo_defines.h" #include "osdep/keycodes.h" #include "input/input.h" #include "input/mouse.h" @@ -39,6 +41,7 @@ extern int enable_mouse_movements; static const char classname[] = "MPlayer - Media player for Win32"; int vo_vm = 0; +static int depthonscreen; // last non-fullscreen extends static int prev_width; static int prev_height; @@ -115,7 +118,7 @@ static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM l xborder = (r2.right - r2.left) - (r.right - r.left); yborder = (r2.bottom - r2.top) - (r.bottom - r.top); wpos->cx -= xborder; wpos->cy -= yborder; - aspect_fit(&wpos->cx, &wpos->cy, wpos->cx, wpos->cy); + aspect_fit(global_vo, &wpos->cx, &wpos->cy, wpos->cx, wpos->cy); wpos->cx += xborder; wpos->cy += yborder; } return 0; @@ -162,7 +165,7 @@ static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM l char cmd_str[40]; snprintf(cmd_str, sizeof(cmd_str), "set_mouse_pos %i %i", GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); - mp_input_queue_cmd(mp_input_parse_cmd(cmd_str)); + mp_input_queue_cmd(global_vo->input_ctx, mp_input_parse_cmd(cmd_str)); } break; case WM_MOUSEWHEEL: @@ -282,7 +285,7 @@ static void updateScreenProperties(void) { vo_screenwidth = dm.dmPelsWidth; vo_screenheight = dm.dmPelsHeight; - vo_depthonscreen = dm.dmBitsPerPel; + depthonscreen = dm.dmBitsPerPel; w32_update_xinerama_info(); } @@ -292,7 +295,7 @@ static void changeMode(void) { dm.dmDriverExtra = 0; dm.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT; - dm.dmBitsPerPel = vo_depthonscreen; + dm.dmBitsPerPel = depthonscreen; dm.dmPelsWidth = vo_screenwidth; dm.dmPelsHeight = vo_screenheight; @@ -302,7 +305,7 @@ static void changeMode(void) { int i; for (i = 0; EnumDisplaySettings(0, i, &dm); ++i) { int score = (dm.dmPelsWidth - o_dwidth) * (dm.dmPelsHeight - o_dheight); - if (dm.dmBitsPerPel != vo_depthonscreen) continue; + if (dm.dmBitsPerPel != depthonscreen) continue; if (dm.dmPelsWidth < o_dwidth) continue; if (dm.dmPelsHeight < o_dheight) continue; @@ -392,7 +395,7 @@ static int createRenderingContext(void) { SetPixelFormat(vo_hdc, pf, &pfd); - mp_msg(MSGT_VO, MSGL_V, "vo: win32: running at %dx%d with depth %d\n", vo_screenwidth, vo_screenheight, vo_depthonscreen); + mp_msg(MSGT_VO, MSGL_V, "vo: win32: running at %dx%d with depth %d\n", vo_screenwidth, vo_screenheight, depthonscreen); ReleaseDC(vo_window, vo_hdc); return 1; @@ -562,7 +565,7 @@ void vo_w32_uninit(void) { mp_msg(MSGT_VO, MSGL_V, "vo: win32: uninit\n"); resetMode(); ShowCursor(1); - vo_depthonscreen = 0; + depthonscreen = 0; DestroyWindow(vo_window); vo_window = 0; UnregisterClass(classname, 0); diff --git a/libvo/x11_common.c b/libvo/x11_common.c index df72ebbfdb..0b070a868b 100644 --- a/libvo/x11_common.c +++ b/libvo/x11_common.c @@ -23,10 +23,12 @@ #include <limits.h> #include "config.h" +#include "options.h" #include "mp_msg.h" #include "mp_fifo.h" #include "libavutil/common.h" #include "x11_common.h" +#include "talloc.h" #ifdef X11_FULLSCREEN @@ -87,56 +89,26 @@ extern int enable_mouse_movements; int fs_layer = WIN_LAYER_ABOVE_DOCK; -static int orig_layer = 0; -static int old_gravity = NorthWestGravity; int stop_xscreensaver = 0; static int dpms_disabled = 0; char *mDisplayName = NULL; -Display *mDisplay = NULL; -Window mRootWin; -int mScreen; -int mLocalDisplay; - -/* output window id */ -int vo_mouse_autohide = 0; -int vo_wm_type = 0; -int vo_fs_type = 0; // needs to be accessible for GUI X11 code -static int vo_fs_flip = 0; + char **vo_fstype_list; /* 1 means that the WM is metacity (broken as hell) */ int metacity_hack = 0; -static Atom XA_NET_SUPPORTED; -static Atom XA_NET_WM_STATE; -static Atom XA_NET_WM_STATE_FULLSCREEN; -static Atom XA_NET_WM_STATE_ABOVE; -static Atom XA_NET_WM_STATE_STAYS_ON_TOP; -static Atom XA_NET_WM_STATE_BELOW; -static Atom XA_NET_WM_PID; -static Atom XA_WIN_PROTOCOLS; -static Atom XA_WIN_LAYER; -static Atom XA_WIN_HINTS; -static Atom XAWM_PROTOCOLS; -static Atom XAWM_DELETE_WINDOW; - -#define XA_INIT(x) XA##x = XInternAtom(mDisplay, #x, False) - -static int vo_old_x = 0; -static int vo_old_y = 0; -static int vo_old_width = 0; -static int vo_old_height = 0; - #ifdef CONFIG_XF86VM XF86VidModeModeInfo **vidmodes = NULL; XF86VidModeModeLine modeline; #endif static int vo_x11_get_fs_type(int supported); - +static void saver_off(Display *); +static void saver_on(Display *); /* * Sends the EWMH fullscreen state event. @@ -145,12 +117,12 @@ static int vo_x11_get_fs_type(int supported); * _NET_WM_STATE_ADD -- add state * _NET_WM_STATE_TOGGLE -- toggle */ -void vo_x11_ewmh_fullscreen(int action) +void vo_x11_ewmh_fullscreen(struct vo_x11_state *x11, int action) { assert(action == _NET_WM_STATE_REMOVE || action == _NET_WM_STATE_ADD || action == _NET_WM_STATE_TOGGLE); - if (vo_fs_type & vo_wm_FULLSCREEN) + if (x11->fs_type & vo_wm_FULLSCREEN) { XEvent xev; @@ -158,17 +130,17 @@ void vo_x11_ewmh_fullscreen(int action) xev.xclient.type = ClientMessage; xev.xclient.serial = 0; xev.xclient.send_event = True; - xev.xclient.message_type = XA_NET_WM_STATE; - xev.xclient.window = vo_window; + xev.xclient.message_type = x11->XA_NET_WM_STATE; + xev.xclient.window = x11->window; xev.xclient.format = 32; xev.xclient.data.l[0] = action; - xev.xclient.data.l[1] = XA_NET_WM_STATE_FULLSCREEN; + xev.xclient.data.l[1] = x11->XA_NET_WM_STATE_FULLSCREEN; xev.xclient.data.l[2] = 0; xev.xclient.data.l[3] = 0; xev.xclient.data.l[4] = 0; /* finally send that damn thing */ - if (!XSendEvent(mDisplay, DefaultRootWindow(mDisplay), False, + if (!XSendEvent(x11->display, DefaultRootWindow(x11->display), False, SubstructureRedirectMask | SubstructureNotifyMask, &xev)) { @@ -177,13 +149,13 @@ void vo_x11_ewmh_fullscreen(int action) } } -void vo_hidecursor(Display * disp, Window win) +static void vo_hidecursor(Display * disp, Window win) { Cursor no_ptr; Pixmap bm_no; XColor black, dummy; Colormap colormap; - static char bm_no_data[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; + const char bm_no_data[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; if (WinID == 0) return; // do not hide if playing on the root window @@ -202,7 +174,7 @@ void vo_hidecursor(Display * disp, Window win) XFreeColors(disp,colormap,&black.pixel,1,0); } -void vo_showcursor(Display * disp, Window win) +static void vo_showcursor(Display * disp, Window win) { if (WinID == 0) return; @@ -278,9 +250,9 @@ static void fstype_dump(int fstype) "[x11] Current fstype setting doesn't honour any X atoms\n"); } -static int net_wm_support_state_test(Atom atom) +static int net_wm_support_state_test(struct vo_x11_state *x11, Atom atom) { -#define NET_WM_STATE_TEST(x) { if (atom == XA_NET_WM_STATE_##x) { mp_msg( MSGT_VO,MSGL_V, "[x11] Detected wm supports " #x " state.\n" ); return vo_wm_##x; } } +#define NET_WM_STATE_TEST(x) { if (atom == x11->XA_NET_WM_STATE_##x) { mp_msg( MSGT_VO,MSGL_V, "[x11] Detected wm supports " #x " state.\n" ); return vo_wm_##x; } } NET_WM_STATE_TEST(FULLSCREEN); NET_WM_STATE_TEST(ABOVE); @@ -289,20 +261,22 @@ static int net_wm_support_state_test(Atom atom) return 0; } -static int x11_get_property(Atom type, Atom ** args, unsigned long *nitems) +static int x11_get_property(struct vo_x11_state *x11, Atom type, Atom ** args, + unsigned long *nitems) { int format; unsigned long bytesafter; return Success == - XGetWindowProperty(mDisplay, mRootWin, type, 0, 16384, False, + XGetWindowProperty(x11->display, x11->rootwin, type, 0, 16384, False, AnyPropertyType, &type, &format, nitems, &bytesafter, (unsigned char **) args) && *nitems > 0; } -static int vo_wm_detect(void) +static int vo_wm_detect(struct vo *vo) { + struct vo_x11_state *x11 = vo->x11; int i; int wm = 0; unsigned long nitems; @@ -312,12 +286,12 @@ static int vo_wm_detect(void) return 0; // -- supports layers - if (x11_get_property(XA_WIN_PROTOCOLS, &args, &nitems)) + if (x11_get_property(x11, x11->XA_WIN_PROTOCOLS, &args, &nitems)) { mp_msg(MSGT_VO, MSGL_V, "[x11] Detected wm supports layers.\n"); for (i = 0; i < nitems; i++) { - if (args[i] == XA_WIN_LAYER) + if (args[i] == x11->XA_WIN_LAYER) { wm |= vo_wm_LAYER; metacity_hack |= 1; @@ -337,11 +311,11 @@ static int vo_wm_detect(void) } } // --- netwm - if (x11_get_property(XA_NET_SUPPORTED, &args, &nitems)) + if (x11_get_property(x11, x11->XA_NET_SUPPORTED, &args, &nitems)) { mp_msg(MSGT_VO, MSGL_V, "[x11] Detected wm supports NetWM.\n"); for (i = 0; i < nitems; i++) - wm |= net_wm_support_state_test(args[i]); + wm |= net_wm_support_state_test(vo->x11, args[i]); XFree(args); } @@ -350,7 +324,8 @@ static int vo_wm_detect(void) return wm; } -static void init_atoms(void) +#define XA_INIT(x) x11->XA##x = XInternAtom(x11->display, #x, False) +static void init_atoms(struct vo_x11_state *x11) { XA_INIT(_NET_SUPPORTED); XA_INIT(_NET_WM_STATE); @@ -366,21 +341,22 @@ static void init_atoms(void) XA_INIT(WM_DELETE_WINDOW); } -void update_xinerama_info(void) { +void update_xinerama_info(struct vo *vo) { + struct MPOpts *opts = vo->opts; int screen = xinerama_screen; xinerama_x = xinerama_y = 0; #ifdef CONFIG_XINERAMA - if (screen >= -1 && XineramaIsActive(mDisplay)) + if (screen >= -1 && XineramaIsActive(vo->x11->display)) { XineramaScreenInfo *screens; int num_screens; - screens = XineramaQueryScreens(mDisplay, &num_screens); + screens = XineramaQueryScreens(vo->x11->display, &num_screens); if (screen >= num_screens) screen = num_screens - 1; if (screen == -1) { - int x = vo_dx + vo_dwidth / 2; - int y = vo_dy + vo_dheight / 2; + int x = vo->dx + vo->dwidth / 2; + int y = vo->dy + vo->dheight / 2; for (screen = num_screens - 1; screen > 0; screen--) { int left = screens[screen].x_org; int right = left + screens[screen].width; @@ -392,19 +368,21 @@ void update_xinerama_info(void) { } if (screen < 0) screen = 0; - vo_screenwidth = screens[screen].width; - vo_screenheight = screens[screen].height; + opts->vo_screenwidth = screens[screen].width; + opts->vo_screenheight = screens[screen].height; xinerama_x = screens[screen].x_org; xinerama_y = screens[screen].y_org; XFree(screens); } #endif - aspect_save_screenres(vo_screenwidth, vo_screenheight); + aspect_save_screenres(vo, opts->vo_screenwidth, opts->vo_screenheight); } -int vo_init(void) +int vo_init(struct vo *vo) { + struct MPOpts *opts = vo->opts; + struct vo_x11_state *x11 = vo->x11; // int mScreen; int depth, bpp; unsigned int mask; @@ -420,9 +398,9 @@ int vo_init(void) if (vo_rootwin) WinID = 0; // use root window - if (vo_depthonscreen) + if (x11->depthonscreen) { - saver_off(mDisplay); + saver_off(x11->display); return 1; // already called } @@ -438,52 +416,52 @@ int vo_init(void) mp_msg(MSGT_VO, MSGL_V, "X11 opening display: %s\n", dispName); - mDisplay = XOpenDisplay(dispName); - if (!mDisplay) + x11->display = XOpenDisplay(dispName); + if (!x11->display) { mp_msg(MSGT_VO, MSGL_ERR, "vo: couldn't open the X11 display (%s)!\n", dispName); return 0; } - mScreen = DefaultScreen(mDisplay); // screen ID - mRootWin = RootWindow(mDisplay, mScreen); // root window ID + x11->screen = DefaultScreen(x11->display); // screen ID + x11->rootwin = RootWindow(x11->display, x11->screen); // root window ID - init_atoms(); + init_atoms(vo->x11); #ifdef CONFIG_XF86VM { int clock; - XF86VidModeGetModeLine(mDisplay, mScreen, &clock, &modeline); - if (!vo_screenwidth) - vo_screenwidth = modeline.hdisplay; - if (!vo_screenheight) - vo_screenheight = modeline.vdisplay; + XF86VidModeGetModeLine(x11->display, x11->screen, &clock, &modeline); + if (!opts->vo_screenwidth) + opts->vo_screenwidth = modeline.hdisplay; + if (!opts->vo_screenheight) + opts->vo_screenheight = modeline.vdisplay; } #endif { - if (!vo_screenwidth) - vo_screenwidth = DisplayWidth(mDisplay, mScreen); - if (!vo_screenheight) - vo_screenheight = DisplayHeight(mDisplay, mScreen); + if (!opts->vo_screenwidth) + opts->vo_screenwidth = DisplayWidth(x11->display, x11->screen); + if (!opts->vo_screenheight) + opts->vo_screenheight = DisplayHeight(x11->display, x11->screen); } // get color depth (from root window, or the best visual): - XGetWindowAttributes(mDisplay, mRootWin, &attribs); + XGetWindowAttributes(x11->display, x11->rootwin, &attribs); depth = attribs.depth; if (depth != 15 && depth != 16 && depth != 24 && depth != 32) { Visual *visual; - depth = vo_find_depth_from_visuals(mDisplay, mScreen, &visual); + depth = vo_find_depth_from_visuals(x11->display, x11->screen, &visual); if (depth != -1) - mXImage = XCreateImage(mDisplay, visual, depth, ZPixmap, + mXImage = XCreateImage(x11->display, visual, depth, ZPixmap, 0, NULL, 1, 1, 8, 1); } else mXImage = - XGetImage(mDisplay, mRootWin, 0, 0, 1, 1, AllPlanes, ZPixmap); + XGetImage(x11->display, x11->rootwin, 0, 0, 1, 1, AllPlanes, ZPixmap); - vo_depthonscreen = depth; // display depth on screen + x11->depthonscreen = depth; // display depth on screen // get bits/pixel from XImage structure: if (mXImage == NULL) @@ -493,15 +471,15 @@ int vo_init(void) { /* * for the depth==24 case, the XImage structures might use - * 24 or 32 bits of data per pixel. The global variable - * vo_depthonscreen stores the amount of data per pixel in the + * 24 or 32 bits of data per pixel. The x11->depthonscreen + * field stores the amount of data per pixel in the * XImage structure! * * Maybe we should rename vo_depthonscreen to (or add) vo_bpp? */ bpp = mXImage->bits_per_pixel; - if ((vo_depthonscreen + 7) / 8 != (bpp + 7) / 8) - vo_depthonscreen = bpp; // by A'rpi + if ((x11->depthonscreen + 7) / 8 != (bpp + 7) / 8) + x11->depthonscreen = bpp; // by A'rpi mask = mXImage->red_mask | mXImage->green_mask | mXImage->blue_mask; mp_msg(MSGT_VO, MSGL_V, @@ -509,12 +487,12 @@ int vo_init(void) mXImage->red_mask, mXImage->green_mask, mXImage->blue_mask); XDestroyImage(mXImage); } - if (((vo_depthonscreen + 7) / 8) == 2) + if (((x11->depthonscreen + 7) / 8) == 2) { if (mask == 0x7FFF) - vo_depthonscreen = 15; + x11->depthonscreen = 15; else if (mask == 0xFFFF) - vo_depthonscreen = 16; + x11->depthonscreen = 16; } // XCloseDisplay( mDisplay ); /* slightly improved local display detection AST */ @@ -523,27 +501,27 @@ int vo_init(void) else if (strncmp(dispName, "localhost:", 10) == 0) dispName += 9; if (*dispName == ':' && atoi(dispName + 1) < 10) - mLocalDisplay = 1; + x11->display_is_local = 1; else - mLocalDisplay = 0; + x11->display_is_local = 0; mp_msg(MSGT_VO, MSGL_V, "vo: X11 running at %dx%d with depth %d and %d bpp (\"%s\" => %s display)\n", - vo_screenwidth, vo_screenheight, depth, vo_depthonscreen, - dispName, mLocalDisplay ? "local" : "remote"); + opts->vo_screenwidth, opts->vo_screenheight, depth, x11->depthonscreen, + dispName, x11->display_is_local ? "local" : "remote"); - vo_wm_type = vo_wm_detect(); + x11->wm_type = vo_wm_detect(vo); - vo_fs_type = vo_x11_get_fs_type(vo_wm_type); + x11->fs_type = vo_x11_get_fs_type(x11->wm_type); - fstype_dump(vo_fs_type); + fstype_dump(x11->fs_type); - saver_off(mDisplay); + saver_off(x11->display); return 1; } -void vo_uninit(void) +void vo_uninit(struct vo_x11_state *x11) { - if (!mDisplay) + if (!x11->display) { mp_msg(MSGT_VO, MSGL_V, "vo: x11 uninit called but X11 not initialized..\n"); @@ -552,9 +530,10 @@ void vo_uninit(void) // if( !vo_depthonscreen ) return; mp_msg(MSGT_VO, MSGL_V, "vo: uninit ...\n"); XSetErrorHandler(NULL); - XCloseDisplay(mDisplay); - vo_depthonscreen = 0; - mDisplay = NULL; + XCloseDisplay(x11->display); + x11->depthonscreen = 0; + x11->display = NULL; + talloc_free(x11); } #include "osdep/keycodes.h" @@ -569,11 +548,12 @@ static const struct keymap keysym_map[] = { {0, 0} }; -static void vo_x11_putkey_ext(int keysym) +static void vo_x11_putkey_ext(struct vo *vo, int keysym) { + struct mp_fifo *f = vo->key_fifo; int mpkey = lookup_keymap_table(keysym_map, keysym); if (mpkey) - mplayer_put_key(mpkey); + mplayer_put_key(f, mpkey); } #endif @@ -612,7 +592,7 @@ static const struct keymap keymap[] = { {0, 0} }; -void vo_x11_putkey(int key) +void vo_x11_putkey(struct vo *vo, int key) { static const char *passthrough_keys = " -+*/<>`~!@#$%^&()_{}:;\"\',.?\\|=[]"; int mpkey = 0; @@ -626,7 +606,7 @@ void vo_x11_putkey(int key) mpkey = lookup_keymap_table(keymap, key); if (mpkey) - mplayer_put_key(mpkey); + mplayer_put_key(vo->key_fifo, mpkey); } @@ -672,12 +652,9 @@ typedef struct static MotifWmHints vo_MotifWmHints; static Atom vo_MotifHints = None; -void vo_x11_decoration(Display * vo_Display, Window w, int d) +void vo_x11_decoration(struct vo *vo, int d) { - static unsigned int olddecor = MWM_DECOR_ALL; - static unsigned int oldfuncs = - MWM_FUNC_MOVE | MWM_FUNC_CLOSE | MWM_FUNC_MINIMIZE | - MWM_FUNC_MAXIMIZE | MWM_FUNC_RESIZE; + struct vo_x11_state *x11 = vo->x11; Atom mtype; int mformat; unsigned long mn, mb; @@ -687,26 +664,27 @@ void vo_x11_decoration(Display * vo_Display, Window w, int d) if (vo_fsmode & 8) { - XSetTransientForHint(vo_Display, w, - RootWindow(vo_Display, mScreen)); + XSetTransientForHint(x11->display, x11->window, + RootWindow(x11->display, x11->screen)); } - vo_MotifHints = XInternAtom(vo_Display, "_MOTIF_WM_HINTS", 0); + vo_MotifHints = XInternAtom(x11->display, "_MOTIF_WM_HINTS", 0); if (vo_MotifHints != None) { if (!d) { MotifWmHints *mhints = NULL; - XGetWindowProperty(vo_Display, w, vo_MotifHints, 0, 20, False, + XGetWindowProperty(x11->display, x11->window, + vo_MotifHints, 0, 20, False, vo_MotifHints, &mtype, &mformat, &mn, &mb, (unsigned char **) &mhints); if (mhints) { if (mhints->flags & MWM_HINTS_DECORATIONS) - olddecor = mhints->decorations; + x11->olddecor = mhints->decorations; if (mhints->flags & MWM_HINTS_FUNCTIONS) - oldfuncs = mhints->functions; + x11->oldfuncs = mhints->functions; XFree(mhints); } } @@ -716,8 +694,8 @@ void vo_x11_decoration(Display * vo_Display, Window w, int d) MWM_HINTS_FUNCTIONS | MWM_HINTS_DECORATIONS; if (d) { - vo_MotifWmHints.functions = oldfuncs; - d = olddecor; + vo_MotifWmHints.functions = x11->oldfuncs; + d = x11->olddecor; } #if 0 vo_MotifWmHints.decorations = @@ -726,110 +704,99 @@ void vo_x11_decoration(Display * vo_Display, Window w, int d) vo_MotifWmHints.decorations = d | ((vo_fsmode & 2) ? MWM_DECOR_MENU : 0); #endif - XChangeProperty(vo_Display, w, vo_MotifHints, vo_MotifHints, 32, + XChangeProperty(x11->display, x11->window, vo_MotifHints, + vo_MotifHints, 32, PropModeReplace, (unsigned char *) &vo_MotifWmHints, (vo_fsmode & 4) ? 4 : 5); } } -void vo_x11_classhint(Display * display, Window window, char *name) +void vo_x11_classhint(struct vo *vo, Window window, char *name) { + struct vo_x11_state *x11 = vo->x11; XClassHint wmClass; pid_t pid = getpid(); wmClass.res_name = name; wmClass.res_class = "MPlayer"; - XSetClassHint(display, window, &wmClass); - XChangeProperty(display, window, XA_NET_WM_PID, XA_CARDINAL, 32, - PropModeReplace, (unsigned char *) &pid, 1); -} - -Window vo_window = None; -GC vo_gc = NULL; -GC f_gc = NULL; -XSizeHints vo_hint; - -#ifdef CONFIG_GUI -void vo_setwindow(Window w, GC g) -{ - vo_window = w; - vo_gc = g; + XSetClassHint(x11->display, window, &wmClass); + XChangeProperty(x11->display, window, x11->XA_NET_WM_PID, XA_CARDINAL, + 32, PropModeReplace, (unsigned char *) &pid, 1); } -#endif -void vo_x11_uninit(void) +void vo_x11_uninit(struct vo *vo) { - saver_on(mDisplay); - if (vo_window != None) - vo_showcursor(mDisplay, vo_window); + struct vo_x11_state *x11 = vo->x11; + saver_on(x11->display); + if (x11->window != None) + vo_showcursor(x11->display, x11->window); - if (f_gc) + if (x11->f_gc) { - XFreeGC(mDisplay, f_gc); - f_gc = NULL; + XFreeGC(vo->x11->display, x11->f_gc); + x11->f_gc = NULL; } #ifdef CONFIG_GUI /* destroy window only if it's not controlled by the GUI */ if (!use_gui) #endif { - if (vo_gc) + if (x11->vo_gc) { - XSetBackground(mDisplay, vo_gc, 0); - XFreeGC(mDisplay, vo_gc); - vo_gc = NULL; + XSetBackground(vo->x11->display, x11->vo_gc, 0); + XFreeGC(vo->x11->display, x11->vo_gc); + x11->vo_gc = NULL; } - if (vo_window != None) + if (x11->window != None) { - XClearWindow(mDisplay, vo_window); + XClearWindow(x11->display, x11->window); if (WinID < 0) { XEvent xev; - XUnmapWindow(mDisplay, vo_window); - XDestroyWindow(mDisplay, vo_window); + XUnmapWindow(x11->display, x11->window); + XDestroyWindow(x11->display, x11->window); do { - XNextEvent(mDisplay, &xev); + XNextEvent(x11->display, &xev); } while (xev.type != DestroyNotify - || xev.xdestroywindow.event != vo_window); + || xev.xdestroywindow.event != x11->window); } - vo_window = None; + x11->window = None; } vo_fs = 0; - vo_old_width = vo_old_height = 0; + x11->vo_old_width = x11->vo_old_height = 0; } } -static unsigned int mouse_timer; -static int mouse_waiting_hide; - -int vo_x11_check_events(Display * mydisplay) +int vo_x11_check_events(struct vo *vo) { + struct vo_x11_state *x11 = vo->x11; + struct MPOpts *opts = vo->opts; + Display *display = vo->x11->display; int ret = 0; XEvent Event; char buf[100]; KeySym keySym; - static XComposeStatus stat; // unsigned long vo_KeyTable[512]; - if ((vo_mouse_autohide) && mouse_waiting_hide && - (GetTimerMS() - mouse_timer >= 1000)) { - vo_hidecursor(mydisplay, vo_window); - mouse_waiting_hide = 0; + if ((x11->vo_mouse_autohide) && x11->mouse_waiting_hide && + (GetTimerMS() - x11->mouse_timer >= 1000)) { + vo_hidecursor(display, x11->window); + x11->mouse_waiting_hide = 0; } - while (XPending(mydisplay)) + while (XPending(display)) { - XNextEvent(mydisplay, &Event); + XNextEvent(display, &Event); #ifdef CONFIG_GUI if (use_gui) { guiGetEvent(0, (char *) &Event); - if (vo_window != Event.xany.window) + if (x11->window != Event.xany.window) continue; } #endif @@ -840,14 +807,14 @@ int vo_x11_check_events(Display * mydisplay) ret |= VO_EVENT_EXPOSE; break; case ConfigureNotify: -// if (!vo_fs && (Event.xconfigure.width == vo_screenwidth || Event.xconfigure.height == vo_screenheight)) break; -// if (vo_fs && Event.xconfigure.width != vo_screenwidth && Event.xconfigure.height != vo_screenheight) break; - if (vo_window == None) +// if (!vo_fs && (Event.xconfigure.width == opts->vo_screenwidth || Event.xconfigure.height == opts->vo_screenheight)) break; +// if (vo_fs && Event.xconfigure.width != opts->vo_screenwidth && Event.xconfigure.height != opts->vo_screenheight) break; + if (x11->window == None) break; { - int old_w = vo_dwidth, old_h = vo_dheight; - vo_x11_update_geometry(); - if (vo_dwidth != old_w || vo_dheight != old_h) + int old_w = vo->dwidth, old_h = vo->dheight; + vo_x11_update_geometry(vo); + if (vo->dwidth != old_w || vo->dheight != old_h) ret |= VO_EVENT_RESIZE; } break; @@ -860,14 +827,14 @@ int vo_x11_check_events(Display * mydisplay) #endif XLookupString(&Event.xkey, buf, sizeof(buf), &keySym, - &stat); + &x11->compose_status); #ifdef XF86XK_AudioPause - vo_x11_putkey_ext(keySym); + vo_x11_putkey_ext(vo, keySym); #endif key = ((keySym & 0xff00) != 0 ? ((keySym & 0x00ff) + 256) : (keySym)); - vo_x11_putkey(key); + vo_x11_putkey(vo, key); ret |= VO_EVENT_KEYPRESS; } break; @@ -876,22 +843,23 @@ int vo_x11_check_events(Display * mydisplay) { char cmd_str[40]; sprintf(cmd_str,"set_mouse_pos %i %i",Event.xmotion.x, Event.xmotion.y); - mp_input_queue_cmd(mp_input_parse_cmd(cmd_str)); + mp_input_queue_cmd(vo->input_ctx, + mp_input_parse_cmd(cmd_str)); } - if (vo_mouse_autohide) + if (x11->vo_mouse_autohide) { - vo_showcursor(mydisplay, vo_window); - mouse_waiting_hide = 1; - mouse_timer = GetTimerMS(); + vo_showcursor(display, x11->window); + x11->mouse_waiting_hide = 1; + x11->mouse_timer = GetTimerMS(); } break; case ButtonPress: - if (vo_mouse_autohide) + if (x11->vo_mouse_autohide) { - vo_showcursor(mydisplay, vo_window); - mouse_waiting_hide = 1; - mouse_timer = GetTimerMS(); + vo_showcursor(display, x11->window); + x11->mouse_waiting_hide = 1; + x11->mouse_timer = GetTimerMS(); } #ifdef CONFIG_GUI // Ignore mouse button 1-3 under GUI. @@ -899,15 +867,16 @@ int vo_x11_check_events(Display * mydisplay) && (Event.xbutton.button <= 3)) break; #endif - mplayer_put_key((MOUSE_BTN0 + Event.xbutton.button - - 1) | MP_KEY_DOWN); + mplayer_put_key(vo->key_fifo, + (MOUSE_BTN0 + Event.xbutton.button - 1) + | MP_KEY_DOWN); break; case ButtonRelease: - if (vo_mouse_autohide) + if (x11->vo_mouse_autohide) { - vo_showcursor(mydisplay, vo_window); - mouse_waiting_hide = 1; - mouse_timer = GetTimerMS(); + vo_showcursor(display, x11->window); + x11->mouse_waiting_hide = 1; + x11->mouse_timer = GetTimerMS(); } #ifdef CONFIG_GUI // Ignore mouse button 1-3 under GUI. @@ -915,12 +884,13 @@ int vo_x11_check_events(Display * mydisplay) && (Event.xbutton.button <= 3)) break; #endif - mplayer_put_key(MOUSE_BTN0 + Event.xbutton.button - 1); + mplayer_put_key(vo->key_fifo, + MOUSE_BTN0 + Event.xbutton.button - 1); break; case PropertyNotify: { char *name = - XGetAtomName(mydisplay, Event.xproperty.atom); + XGetAtomName(display, Event.xproperty.atom); if (!name) break; @@ -931,14 +901,14 @@ int vo_x11_check_events(Display * mydisplay) } break; case MapNotify: - vo_hint.win_gravity = old_gravity; - XSetWMNormalHints(mDisplay, vo_window, &vo_hint); - vo_fs_flip = 0; + x11->vo_hint.win_gravity = x11->old_gravity; + XSetWMNormalHints(display, x11->window, &x11->vo_hint); + x11->fs_flip = 0; break; case ClientMessage: - if (Event.xclient.message_type == XAWM_PROTOCOLS && - Event.xclient.data.l[0] == XAWM_DELETE_WINDOW) - mplayer_put_key(KEY_CLOSE_WIN); + if (Event.xclient.message_type == x11->XAWM_PROTOCOLS && + Event.xclient.data.l[0] == x11->XAWM_DELETE_WINDOW) + mplayer_put_key(vo->key_fifo, KEY_CLOSE_WIN); break; } } @@ -948,69 +918,72 @@ int vo_x11_check_events(Display * mydisplay) /** * \brief sets the size and position of the non-fullscreen window. */ -void vo_x11_nofs_sizepos(int x, int y, int width, int height) +static void vo_x11_nofs_sizepos(struct vo *vo, int x, int y, + int width, int height) { - vo_x11_sizehint(x, y, width, height, 0); + struct vo_x11_state *x11 = vo->x11; + vo_x11_sizehint(vo, x, y, width, height, 0); if (vo_fs) { - vo_old_x = x; - vo_old_y = y; - vo_old_width = width; - vo_old_height = height; + x11->vo_old_x = x; + x11->vo_old_y = y; + x11->vo_old_width = width; + x11->vo_old_height = height; } else { - vo_dwidth = width; - vo_dheight = height; - XMoveResizeWindow(mDisplay, vo_window, x, y, width, height); + vo->dwidth = width; + vo->dheight = height; + XMoveResizeWindow(vo->x11->display, vo->x11->window, x, y, width, height); } } -void vo_x11_sizehint(int x, int y, int width, int height, int max) +void vo_x11_sizehint(struct vo *vo, int x, int y, int width, int height, int max) { - vo_hint.flags = 0; + struct vo_x11_state *x11 = vo->x11; + x11->vo_hint.flags = 0; if (vo_keepaspect) { - vo_hint.flags |= PAspect; - vo_hint.min_aspect.x = width; - vo_hint.min_aspect.y = height; - vo_hint.max_aspect.x = width; - vo_hint.max_aspect.y = height; + x11->vo_hint.flags |= PAspect; + x11->vo_hint.min_aspect.x = width; + x11->vo_hint.min_aspect.y = height; + x11->vo_hint.max_aspect.x = width; + x11->vo_hint.max_aspect.y = height; } - vo_hint.flags |= PPosition | PSize; - vo_hint.x = x; - vo_hint.y = y; - vo_hint.width = width; - vo_hint.height = height; + x11->vo_hint.flags |= PPosition | PSize; + x11->vo_hint.x = x; + x11->vo_hint.y = y; + x11->vo_hint.width = width; + x11->vo_hint.height = height; if (max) { - vo_hint.flags |= PMaxSize; - vo_hint.max_width = width; - vo_hint.max_height = height; + x11->vo_hint.flags |= PMaxSize; + x11->vo_hint.max_width = width; + x11->vo_hint.max_height = height; } else { - vo_hint.max_width = 0; - vo_hint.max_height = 0; + x11->vo_hint.max_width = 0; + x11->vo_hint.max_height = 0; } // Set minimum height/width to 4 to avoid off-by-one errors // and because mga_vid requires a minimal size of 4 pixels. - vo_hint.flags |= PMinSize; - vo_hint.min_width = vo_hint.min_height = 4; + x11->vo_hint.flags |= PMinSize; + x11->vo_hint.min_width = x11->vo_hint.min_height = 4; // Set the base size. A window manager might display the window // size to the user relative to this. // Setting these to width/height might be nice, but e.g. fluxbox can't handle it. - vo_hint.flags |= PBaseSize; - vo_hint.base_width = 0 /*width*/; - vo_hint.base_height = 0 /*height*/; + x11->vo_hint.flags |= PBaseSize; + x11->vo_hint.base_width = 0 /*width*/; + x11->vo_hint.base_height = 0 /*height*/; - vo_hint.flags |= PWinGravity; - vo_hint.win_gravity = StaticGravity; - XSetWMNormalHints(mDisplay, vo_window, &vo_hint); + x11->vo_hint.flags |= PWinGravity; + x11->vo_hint.win_gravity = StaticGravity; + XSetWMNormalHints(x11->display, x11->window, &x11->vo_hint); } -static int vo_x11_get_gnome_layer(Display * mDisplay, Window win) +static int vo_x11_get_gnome_layer(struct vo_x11_state *x11, Window win) { Atom type; int format; @@ -1018,7 +991,7 @@ static int vo_x11_get_gnome_layer(Display * mDisplay, Window win) unsigned long bytesafter; unsigned short *args = NULL; - if (XGetWindowProperty(mDisplay, win, XA_WIN_LAYER, 0, 16384, + if (XGetWindowProperty(x11->display, win, x11->XA_WIN_LAYER, 0, 16384, False, AnyPropertyType, &type, &format, &nitems, &bytesafter, (unsigned char **) &args) == Success @@ -1032,7 +1005,7 @@ static int vo_x11_get_gnome_layer(Display * mDisplay, Window win) } // -Window vo_x11_create_smooth_window(Display * mDisplay, Window mRoot, +static Window vo_x11_create_smooth_window(struct vo_x11_state *x11, Window mRoot, Visual * vis, int x, int y, unsigned int width, unsigned int height, int depth, Colormap col_map) @@ -1052,12 +1025,12 @@ Window vo_x11_create_smooth_window(Display * mDisplay, Window mRoot, xswa.bit_gravity = StaticGravity; ret_win = - XCreateWindow(mDisplay, mRootWin, x, y, width, height, 0, depth, + XCreateWindow(x11->display, x11->rootwin, x, y, width, height, 0, depth, CopyFromParent, vis, xswamask, &xswa); - XSetWMProtocols(mDisplay, ret_win, &XAWM_DELETE_WINDOW, 1); - if (!f_gc) - f_gc = XCreateGC(mDisplay, ret_win, 0, 0); - XSetForeground(mDisplay, f_gc, 0); + XSetWMProtocols(x11->display, ret_win, &x11->XAWM_DELETE_WINDOW, 1); + if (!x11->f_gc) + x11->f_gc = XCreateGC(x11->display, ret_win, 0, 0); + XSetForeground(x11->display, x11->f_gc, 0); return ret_win; } @@ -1078,165 +1051,174 @@ Window vo_x11_create_smooth_window(Display * mDisplay, Window mRoot, * This also does the grunt-work like setting Window Manager hints etc. * If vo_window is already set it just moves and resizes it. */ -void vo_x11_create_vo_window(XVisualInfo *vis, int x, int y, +void vo_x11_create_vo_window(struct vo *vo, XVisualInfo *vis, int x, int y, unsigned int width, unsigned int height, int flags, Colormap col_map, const char *classname, const char *title) { + struct MPOpts *opts = vo->opts; + struct vo_x11_state *x11 = vo->x11; + Display *mDisplay = vo->x11->display; XGCValues xgcv; if (WinID >= 0) { - vo_window = WinID ? (Window)WinID : mRootWin; + x11->window = WinID ? (Window)WinID : x11->rootwin; if (col_map != CopyFromParent) { unsigned long xswamask = CWColormap; XSetWindowAttributes xswa; xswa.colormap = col_map; - XUnmapWindow(mDisplay, vo_window); - XChangeWindowAttributes(mDisplay, vo_window, xswamask, &xswa); - XMapWindow(mDisplay, vo_window); + XUnmapWindow(mDisplay, x11->window); + XChangeWindowAttributes(mDisplay, x11->window, xswamask, &xswa); + XMapWindow(mDisplay, x11->window); } - if (WinID) vo_x11_update_geometry(); - vo_x11_selectinput_witherr(mDisplay, vo_window, + if (WinID) vo_x11_update_geometry(vo); + vo_x11_selectinput_witherr(mDisplay, x11->window, StructureNotifyMask | KeyPressMask | PointerMotionMask | ButtonPressMask | ButtonReleaseMask | ExposureMask); goto final; } - if (vo_window == None) { + if (x11->window == None) { XSizeHints hint; XEvent xev; vo_fs = 0; - vo_dwidth = width; - vo_dheight = height; - vo_window = vo_x11_create_smooth_window(mDisplay, mRootWin, vis->visual, + vo->dwidth = width; + vo->dheight = height; + x11->window = vo_x11_create_smooth_window(x11, x11->rootwin, vis->visual, x, y, width, height, vis->depth, col_map); - vo_x11_classhint(mDisplay, vo_window, classname); - XStoreName(mDisplay, vo_window, title); - vo_hidecursor(mDisplay, vo_window); - XSelectInput(mDisplay, vo_window, StructureNotifyMask); + vo_x11_classhint(vo, x11->window, classname); + XStoreName(mDisplay, x11->window, title); + vo_hidecursor(mDisplay, x11->window); + XSelectInput(mDisplay, x11->window, StructureNotifyMask); hint.x = x; hint.y = y; hint.width = width; hint.height = height; hint.flags = PPosition | PSize; - XSetStandardProperties(mDisplay, vo_window, title, title, None, NULL, 0, &hint); - vo_x11_sizehint(x, y, width, height, 0); - if (!vo_border) vo_x11_decoration(mDisplay, vo_window, 0); + XSetStandardProperties(mDisplay, x11->window, title, title, None, NULL, 0, &hint); + vo_x11_sizehint(vo, x, y, width, height, 0); + if (!vo_border) vo_x11_decoration(vo, 0); // map window - XMapWindow(mDisplay, vo_window); - XClearWindow(mDisplay, vo_window); + XMapWindow(mDisplay, x11->window); + XClearWindow(mDisplay, x11->window); // wait for map do { XNextEvent(mDisplay, &xev); - } while (xev.type != MapNotify || xev.xmap.event != vo_window); - XSelectInput(mDisplay, vo_window, NoEventMask); + } while (xev.type != MapNotify || xev.xmap.event != x11->window); + XSelectInput(mDisplay, x11->window, NoEventMask); XSync(mDisplay, False); - vo_x11_selectinput_witherr(mDisplay, vo_window, + vo_x11_selectinput_witherr(mDisplay, x11->window, StructureNotifyMask | KeyPressMask | PointerMotionMask | ButtonPressMask | ButtonReleaseMask | ExposureMask); } - if (vo_ontop) vo_x11_setlayer(mDisplay, vo_window, vo_ontop); - vo_x11_nofs_sizepos(vo_dx, vo_dy, width, height); + if (opts->vo_ontop) vo_x11_setlayer(vo, x11->window, opts->vo_ontop); + vo_x11_nofs_sizepos(vo, vo->dx, vo->dy, width, height); if (!!vo_fs != !!(flags & VOFLAG_FULLSCREEN)) - vo_x11_fullscreen(); + vo_x11_fullscreen(vo); final: - if (vo_gc != None) - XFreeGC(mDisplay, vo_gc); - vo_gc = XCreateGC(mDisplay, vo_window, GCForeground, &xgcv); + if (x11->vo_gc != None) + XFreeGC(mDisplay, x11->vo_gc); + x11->vo_gc = XCreateGC(mDisplay, x11->window, GCForeground, &xgcv); XSync(mDisplay, False); - vo_mouse_autohide = 1; + x11->vo_mouse_autohide = 1; } -void vo_x11_clearwindow_part(Display * mDisplay, Window vo_window, +void vo_x11_clearwindow_part(struct vo *vo, Window vo_window, int img_width, int img_height, int use_fs) { + struct vo_x11_state *x11 = vo->x11; + struct MPOpts *opts = vo->opts; + Display *mDisplay = vo->x11->display; int u_dheight, u_dwidth, left_ov, left_ov2; - if (!f_gc) + if (!x11->f_gc) return; - u_dheight = use_fs ? vo_screenheight : vo_dheight; - u_dwidth = use_fs ? vo_screenwidth : vo_dwidth; + u_dheight = use_fs ? opts->vo_screenheight : vo->dheight; + u_dwidth = use_fs ? opts->vo_screenwidth : vo->dwidth; if ((u_dheight <= img_height) && (u_dwidth <= img_width)) return; left_ov = (u_dheight - img_height) / 2; left_ov2 = (u_dwidth - img_width) / 2; - XFillRectangle(mDisplay, vo_window, f_gc, 0, 0, u_dwidth, left_ov); - XFillRectangle(mDisplay, vo_window, f_gc, 0, u_dheight - left_ov - 1, + XFillRectangle(mDisplay, vo_window, x11->f_gc, 0, 0, u_dwidth, left_ov); + XFillRectangle(mDisplay, vo_window, x11->f_gc, 0, u_dheight - left_ov - 1, u_dwidth, left_ov + 1); if (u_dwidth > img_width) { - XFillRectangle(mDisplay, vo_window, f_gc, 0, left_ov, left_ov2, + XFillRectangle(mDisplay, vo_window, x11->f_gc, 0, left_ov, left_ov2, img_height); - XFillRectangle(mDisplay, vo_window, f_gc, u_dwidth - left_ov2 - 1, + XFillRectangle(mDisplay, vo_window, x11->f_gc, u_dwidth - left_ov2 - 1, left_ov, left_ov2 + 1, img_height); } XFlush(mDisplay); } -void vo_x11_clearwindow(Display * mDisplay, Window vo_window) +void vo_x11_clearwindow(struct vo *vo, Window vo_window) { - if (!f_gc) + struct vo_x11_state *x11 = vo->x11; + struct MPOpts *opts = vo->opts; + if (!x11->f_gc) return; - XFillRectangle(mDisplay, vo_window, f_gc, 0, 0, vo_screenwidth, - vo_screenheight); + XFillRectangle(x11->display, vo_window, x11->f_gc, 0, 0, + opts->vo_screenwidth, opts->vo_screenheight); // - XFlush(mDisplay); + XFlush(x11->display); } -void vo_x11_setlayer(Display * mDisplay, Window vo_window, int layer) +void vo_x11_setlayer(struct vo *vo, Window vo_window, int layer) { + struct vo_x11_state *x11 = vo->x11; if (WinID >= 0) return; - if (vo_fs_type & vo_wm_LAYER) + if (x11->fs_type & vo_wm_LAYER) { XClientMessageEvent xev; - if (!orig_layer) - orig_layer = vo_x11_get_gnome_layer(mDisplay, vo_window); + if (!x11->orig_layer) + x11->orig_layer = vo_x11_get_gnome_layer(x11, vo_window); memset(&xev, 0, sizeof(xev)); xev.type = ClientMessage; - xev.display = mDisplay; + xev.display = x11->display; xev.window = vo_window; - xev.message_type = XA_WIN_LAYER; + xev.message_type = x11->XA_WIN_LAYER; xev.format = 32; - xev.data.l[0] = layer ? fs_layer : orig_layer; // if not fullscreen, stay on default layer + xev.data.l[0] = layer ? fs_layer : x11->orig_layer; // if not fullscreen, stay on default layer xev.data.l[1] = CurrentTime; mp_msg(MSGT_VO, MSGL_V, "[x11] Layered style stay on top (layer %ld).\n", xev.data.l[0]); - XSendEvent(mDisplay, mRootWin, False, SubstructureNotifyMask, + XSendEvent(x11->display, x11->rootwin, False, SubstructureNotifyMask, (XEvent *) & xev); - } else if (vo_fs_type & vo_wm_NETWM) + } else if (x11->fs_type & vo_wm_NETWM) { XClientMessageEvent xev; char *state; memset(&xev, 0, sizeof(xev)); xev.type = ClientMessage; - xev.message_type = XA_NET_WM_STATE; - xev.display = mDisplay; + xev.message_type = x11->XA_NET_WM_STATE; + xev.display = x11->display; xev.window = vo_window; xev.format = 32; xev.data.l[0] = layer; - if (vo_fs_type & vo_wm_STAYS_ON_TOP) - xev.data.l[1] = XA_NET_WM_STATE_STAYS_ON_TOP; - else if (vo_fs_type & vo_wm_ABOVE) - xev.data.l[1] = XA_NET_WM_STATE_ABOVE; - else if (vo_fs_type & vo_wm_FULLSCREEN) - xev.data.l[1] = XA_NET_WM_STATE_FULLSCREEN; - else if (vo_fs_type & vo_wm_BELOW) + if (x11->fs_type & vo_wm_STAYS_ON_TOP) + xev.data.l[1] = x11->XA_NET_WM_STATE_STAYS_ON_TOP; + else if (x11->fs_type & vo_wm_ABOVE) + xev.data.l[1] = x11->XA_NET_WM_STATE_ABOVE; + else if (x11->fs_type & vo_wm_FULLSCREEN) + xev.data.l[1] = x11->XA_NET_WM_STATE_FULLSCREEN; + else if (x11->fs_type & vo_wm_BELOW) // This is not fallback. We can safely assume that the situation // where only NETWM_STATE_BELOW is supported doesn't exist. - xev.data.l[1] = XA_NET_WM_STATE_BELOW; + xev.data.l[1] = x11->XA_NET_WM_STATE_BELOW; - XSendEvent(mDisplay, mRootWin, False, SubstructureRedirectMask, + XSendEvent(x11->display, x11->rootwin, False, SubstructureRedirectMask, (XEvent *) & xev); - state = XGetAtomName(mDisplay, xev.data.l[1]); + state = XGetAtomName(x11->display, xev.data.l[1]); mp_msg(MSGT_VO, MSGL_V, "[x11] NET style stay on top (layer %d). Using state %s.\n", layer, state); @@ -1317,107 +1299,115 @@ static int vo_x11_get_fs_type(int supported) } /** - * \brief update vo_dx, vo_dy, vo_dwidth and vo_dheight with current values of vo_window - * \return returns current color depth of vo_window + * \brief update vo->dx, vo->dy, vo->dwidth and vo->dheight with current values of vo->x11->window + * \return returns current color depth of vo->x11->window */ -int vo_x11_update_geometry(void) { +int vo_x11_update_geometry(struct vo *vo) +{ + struct vo_x11_state *x11 = vo->x11; unsigned depth, w, h; int dummy_int; Window dummy_win; - XGetGeometry(mDisplay, vo_window, &dummy_win, &dummy_int, &dummy_int, + XGetGeometry(x11->display, x11->window, &dummy_win, &dummy_int, &dummy_int, &w, &h, &dummy_int, &depth); - if (w <= INT_MAX && h <= INT_MAX) { vo_dwidth = w; vo_dheight = h; } - XTranslateCoordinates(mDisplay, vo_window, mRootWin, 0, 0, &vo_dx, &vo_dy, - &dummy_win); + if (w <= INT_MAX && h <= INT_MAX) { + vo->dwidth = w; + vo->dheight = h; + } + XTranslateCoordinates(x11->display, x11->window, x11->rootwin, 0, 0, + &vo->dx, &vo->dy, &dummy_win); return depth <= INT_MAX ? depth : 0; } -void vo_x11_fullscreen(void) +void vo_x11_fullscreen(struct vo *vo) { + struct MPOpts *opts = vo->opts; + struct vo_x11_state *x11 = vo->x11; int x, y, w, h; - if (WinID >= 0 || vo_fs_flip) + if (WinID >= 0 || x11->fs_flip) return; if (vo_fs) { // fs->win - if ( ! (vo_fs_type & vo_wm_FULLSCREEN) ) // not needed with EWMH fs + if ( ! (x11->fs_type & vo_wm_FULLSCREEN) ) // not needed with EWMH fs { - x = vo_old_x; - y = vo_old_y; - w = vo_old_width; - h = vo_old_height; + x = x11->vo_old_x; + y = x11->vo_old_y; + w = x11->vo_old_width; + h = x11->vo_old_height; } - vo_x11_ewmh_fullscreen(_NET_WM_STATE_REMOVE); // removes fullscreen state if wm supports EWMH + vo_x11_ewmh_fullscreen(x11, _NET_WM_STATE_REMOVE); // removes fullscreen state if wm supports EWMH vo_fs = VO_FALSE; } else { // win->fs - vo_x11_ewmh_fullscreen(_NET_WM_STATE_ADD); // sends fullscreen state to be added if wm supports EWMH + vo_x11_ewmh_fullscreen(x11, _NET_WM_STATE_ADD); // sends fullscreen state to be added if wm supports EWMH vo_fs = VO_TRUE; - if ( ! (vo_fs_type & vo_wm_FULLSCREEN) ) // not needed with EWMH fs + if ( ! (x11->fs_type & vo_wm_FULLSCREEN) ) // not needed with EWMH fs { - vo_old_x = vo_dx; - vo_old_y = vo_dy; - vo_old_width = vo_dwidth; - vo_old_height = vo_dheight; + x11->vo_old_x = vo->dx; + x11->vo_old_y = vo->dy; + x11->vo_old_width = vo->dwidth; + x11->vo_old_height = vo->dheight; } - update_xinerama_info(); + update_xinerama_info(vo); x = xinerama_x; y = xinerama_y; - w = vo_screenwidth; - h = vo_screenheight; + w = opts->vo_screenwidth; + h = opts->vo_screenheight; } { long dummy; - XGetWMNormalHints(mDisplay, vo_window, &vo_hint, &dummy); - if (!(vo_hint.flags & PWinGravity)) - old_gravity = NorthWestGravity; + XGetWMNormalHints(x11->display, x11->window, &x11->vo_hint, &dummy); + if (!(x11->vo_hint.flags & PWinGravity)) + x11->old_gravity = NorthWestGravity; else - old_gravity = vo_hint.win_gravity; + x11->old_gravity = x11->vo_hint.win_gravity; } - if (vo_wm_type == 0 && !(vo_fsmode & 16)) + if (x11->wm_type == 0 && !(vo_fsmode & 16)) { - XUnmapWindow(mDisplay, vo_window); // required for MWM - XWithdrawWindow(mDisplay, vo_window, mScreen); - vo_fs_flip = 1; + XUnmapWindow(x11->display, x11->window); // required for MWM + XWithdrawWindow(x11->display, x11->window, x11->screen); + x11->fs_flip = 1; } - if ( ! (vo_fs_type & vo_wm_FULLSCREEN) ) // not needed with EWMH fs + if ( ! (x11->fs_type & vo_wm_FULLSCREEN) ) // not needed with EWMH fs { - vo_x11_decoration(mDisplay, vo_window, vo_border && !vo_fs); - vo_x11_sizehint(x, y, w, h, 0); - vo_x11_setlayer(mDisplay, vo_window, vo_fs); + vo_x11_decoration(vo, vo_border && !vo_fs); + vo_x11_sizehint(vo, x, y, w, h, 0); + vo_x11_setlayer(vo, x11->window, vo_fs); - XMoveResizeWindow(mDisplay, vo_window, x, y, w, h); + XMoveResizeWindow(x11->display, x11->window, x, y, w, h); } /* some WMs lose ontop after fullscreen */ - if ((!(vo_fs)) & vo_ontop) - vo_x11_setlayer(mDisplay, vo_window, vo_ontop); - - XMapRaised(mDisplay, vo_window); - if ( ! (vo_fs_type & vo_wm_FULLSCREEN) ) // some WMs change window pos on map - XMoveResizeWindow(mDisplay, vo_window, x, y, w, h); - XRaiseWindow(mDisplay, vo_window); - XFlush(mDisplay); + if ((!(vo_fs)) & opts->vo_ontop) + vo_x11_setlayer(vo, x11->window, opts->vo_ontop); + + XMapRaised(x11->display, x11->window); + if ( ! (x11->fs_type & vo_wm_FULLSCREEN) ) // some WMs change window pos on map + XMoveResizeWindow(x11->display, x11->window, x, y, w, h); + XRaiseWindow(x11->display, x11->window); + XFlush(x11->display); } -void vo_x11_ontop(void) +void vo_x11_ontop(struct vo *vo) { - vo_ontop = (!(vo_ontop)); + struct MPOpts *opts = vo->opts; + opts->vo_ontop = !opts->vo_ontop; - vo_x11_setlayer(mDisplay, vo_window, vo_ontop); + vo_x11_setlayer(vo, vo->x11->window, opts->vo_ontop); } -void vo_x11_border(void) +void vo_x11_border(struct vo *vo) { vo_border = !vo_border; - vo_x11_decoration(mDisplay, vo_window, vo_border && !vo_fs); + vo_x11_decoration(vo, vo_border && !vo_fs); } /* @@ -1427,19 +1417,19 @@ void vo_x11_border(void) static int screensaver_off; static unsigned int time_last; -void xscreensaver_heartbeat(void) +void xscreensaver_heartbeat(struct vo_x11_state *x11) { unsigned int time = GetTimerMS(); - if (mDisplay && screensaver_off && (time - time_last) > 30000) + if (x11->display && screensaver_off && (time - time_last) > 30000) { time_last = time; - XResetScreenSaver(mDisplay); + XResetScreenSaver(x11->display); } } -static int xss_suspend(Bool suspend) +static int xss_suspend(Display *mDisplay, Bool suspend) { #ifndef CONFIG_XSS return 0; @@ -1459,13 +1449,13 @@ static int xss_suspend(Bool suspend) * End of XScreensaver stuff */ -void saver_on(Display * mDisplay) +static void saver_on(Display * mDisplay) { if (!screensaver_off) return; screensaver_off = 0; - if (xss_suspend(False)) + if (xss_suspend(mDisplay, False)) return; #ifdef CONFIG_XDPMS if (dpms_disabled) @@ -1499,14 +1489,14 @@ void saver_on(Display * mDisplay) #endif } -void saver_off(Display * mDisplay) +static void saver_off(Display * mDisplay) { int nothing; if (screensaver_off) return; screensaver_off = 1; - if (xss_suspend(True)) + if (xss_suspend(mDisplay, True)) return; #ifdef CONFIG_XDPMS if (DPMSQueryExtension(mDisplay, ¬hing, ¬hing)) @@ -1581,12 +1571,15 @@ void vo_x11_selectinput_witherr(Display * display, Window w, } #ifdef CONFIG_XF86VM -void vo_vm_switch(void) +void vo_vm_switch(struct vo *vo) { + struct vo_x11_state *x11 = vo->x11; + struct MPOpts *opts = vo->opts; + Display *mDisplay = x11->display; int vm_event, vm_error; int vm_ver, vm_rev; int i, j, have_vm = 0; - int X = vo_dwidth, Y = vo_dheight; + int X = vo->dwidth, Y = vo->dheight; int modeline_width, modeline_height; int modecount; @@ -1605,7 +1598,7 @@ void vo_vm_switch(void) if (have_vm) { if (vidmodes == NULL) - XF86VidModeGetAllModeLines(mDisplay, mScreen, &modecount, + XF86VidModeGetAllModeLines(mDisplay, x11->screen, &modecount, &vidmodes); j = 0; modeline_width = vidmodes[0]->hdisplay; @@ -1624,26 +1617,28 @@ void vo_vm_switch(void) mp_msg(MSGT_VO, MSGL_INFO, MSGTR_SelectedVideoMode, modeline_width, modeline_height, X, Y); - XF86VidModeLockModeSwitch(mDisplay, mScreen, 0); - XF86VidModeSwitchToMode(mDisplay, mScreen, vidmodes[j]); - XF86VidModeSwitchToMode(mDisplay, mScreen, vidmodes[j]); + XF86VidModeLockModeSwitch(mDisplay, x11->screen, 0); + XF86VidModeSwitchToMode(mDisplay, x11->screen, vidmodes[j]); + XF86VidModeSwitchToMode(mDisplay, x11->screen, vidmodes[j]); // FIXME: all this is more of a hack than proper solution - X = (vo_screenwidth - modeline_width) / 2; - Y = (vo_screenheight - modeline_height) / 2; - XF86VidModeSetViewPort(mDisplay, mScreen, X, Y); - vo_dx = X; - vo_dy = Y; - vo_dwidth = modeline_width; - vo_dheight = modeline_height; - aspect_save_screenres(modeline_width, modeline_height); + X = (opts->vo_screenwidth - modeline_width) / 2; + Y = (opts->vo_screenheight - modeline_height) / 2; + XF86VidModeSetViewPort(mDisplay, x11->screen, X, Y); + vo->dx = X; + vo->dy = Y; + vo->dwidth = modeline_width; + vo->dheight = modeline_height; + aspect_save_screenres(vo, modeline_width, modeline_height); } } -void vo_vm_close(void) +void vo_vm_close(struct vo *vo) { + Display *dpy = vo->x11->display; + struct MPOpts *opts = vo->opts; #ifdef CONFIG_GUI - if (vidmodes != NULL && vo_window != None) + if (vidmodes != NULL && vo->x11->vo_window != None) #else if (vidmodes != NULL) #endif @@ -1652,20 +1647,20 @@ void vo_vm_close(void) free(vidmodes); vidmodes = NULL; - XF86VidModeGetAllModeLines(mDisplay, mScreen, &modecount, + XF86VidModeGetAllModeLines(dpy, vo->x11->screen, &modecount, &vidmodes); for (i = 0; i < modecount; i++) - if ((vidmodes[i]->hdisplay == vo_screenwidth) - && (vidmodes[i]->vdisplay == vo_screenheight)) + if ((vidmodes[i]->hdisplay == opts->vo_screenwidth) + && (vidmodes[i]->vdisplay == opts->vo_screenheight)) { mp_msg(MSGT_VO, MSGL_INFO, "Returning to original mode %dx%d\n", - vo_screenwidth, vo_screenheight); + opts->vo_screenwidth, opts->vo_screenheight); break; } - XF86VidModeSwitchToMode(mDisplay, mScreen, vidmodes[i]); - XF86VidModeSwitchToMode(mDisplay, mScreen, vidmodes[i]); + XF86VidModeSwitchToMode(dpy, vo->x11->screen, vidmodes[i]); + XF86VidModeSwitchToMode(dpy, vo->x11->screen, vidmodes[i]); free(vidmodes); vidmodes = NULL; } @@ -1733,12 +1728,13 @@ static XColor cols[256]; static int cm_size, red_mask, green_mask, blue_mask; -Colormap vo_x11_create_colormap(XVisualInfo * vinfo) +Colormap vo_x11_create_colormap(struct vo *vo, XVisualInfo *vinfo) { + struct vo_x11_state *x11 = vo->x11; unsigned k, r, g, b, ru, gu, bu, m, rv, gv, bv, rvu, gvu, bvu; if (vinfo->class != DirectColor) - return XCreateColormap(mDisplay, mRootWin, vinfo->visual, + return XCreateColormap(x11->display, x11->rootwin, vinfo->visual, AllocNone); /* can this function get called twice or more? */ @@ -1782,8 +1778,8 @@ Colormap vo_x11_create_colormap(XVisualInfo * vinfo) gv += gvu; bv += bvu; } - cmap = XCreateColormap(mDisplay, mRootWin, vinfo->visual, AllocAll); - XStoreColors(mDisplay, cmap, cols, cm_size); + cmap = XCreateColormap(x11->display, x11->rootwin, vinfo->visual, AllocAll); + XStoreColors(x11->display, cmap, cols, cm_size); return cmap; } @@ -1810,7 +1806,7 @@ static int transform_color(float val, return (unsigned short) (s * 65535); } -uint32_t vo_x11_set_equalizer(char *name, int value) +uint32_t vo_x11_set_equalizer(struct vo *vo, char *name, int value) { float gamma, brightness, contrast; float rf, gf, bf; @@ -1856,8 +1852,8 @@ uint32_t vo_x11_set_equalizer(char *name, int value) cols[k].blue = transform_color(bf * k, brightness, contrast, gamma); } - XStoreColors(mDisplay, cmap, cols, cm_size); - XFlush(mDisplay); + XStoreColors(vo->x11->display, cmap, cols, cm_size); + XFlush(vo->x11->display); return VO_TRUE; } @@ -1877,7 +1873,7 @@ uint32_t vo_x11_get_equalizer(char *name, int *value) } #ifdef CONFIG_XV -int vo_xv_set_eq(uint32_t xv_port, char *name, int value) +int vo_xv_set_eq(struct vo *vo, uint32_t xv_port, char *name, int value) { XvAttribute *attributes; int i, howmany, xv_atom; @@ -1885,11 +1881,11 @@ int vo_xv_set_eq(uint32_t xv_port, char *name, int value) mp_dbg(MSGT_VO, MSGL_V, "xv_set_eq called! (%s, %d)\n", name, value); /* get available attributes */ - attributes = XvQueryPortAttributes(mDisplay, xv_port, &howmany); + attributes = XvQueryPortAttributes(vo->x11->display, xv_port, &howmany); for (i = 0; i < howmany && attributes; i++) if (attributes[i].flags & XvSettable) { - xv_atom = XInternAtom(mDisplay, attributes[i].name, True); + xv_atom = XInternAtom(vo->x11->display, attributes[i].name, True); /* since we have SET_DEFAULTS first in our list, we can check if it's available then trigger it if it's ok so that the other values are at default upon query */ if (xv_atom != None) @@ -1940,32 +1936,32 @@ int vo_xv_set_eq(uint32_t xv_port, char *name, int value) port_value = (port_value + 100) * (port_max - port_min) / 200 + port_min; - XvSetPortAttribute(mDisplay, xv_port, xv_atom, port_value); + XvSetPortAttribute(vo->x11->display, xv_port, xv_atom, port_value); return VO_TRUE; } } return VO_FALSE; } -int vo_xv_get_eq(uint32_t xv_port, char *name, int *value) +int vo_xv_get_eq(struct vo *vo, uint32_t xv_port, char *name, int *value) { XvAttribute *attributes; int i, howmany, xv_atom; /* get available attributes */ - attributes = XvQueryPortAttributes(mDisplay, xv_port, &howmany); + attributes = XvQueryPortAttributes(vo->x11->display, xv_port, &howmany); for (i = 0; i < howmany && attributes; i++) if (attributes[i].flags & XvGettable) { - xv_atom = XInternAtom(mDisplay, attributes[i].name, True); + xv_atom = XInternAtom(vo->x11->display, attributes[i].name, True); /* since we have SET_DEFAULTS first in our list, we can check if it's available then trigger it if it's ok so that the other values are at default upon query */ if (xv_atom != None) { int val, port_value = 0, port_min, port_max; - XvGetPortAttribute(mDisplay, xv_port, xv_atom, + XvGetPortAttribute(vo->x11->display, xv_port, xv_atom, &port_value); port_min = attributes[i].min_value; @@ -2013,11 +2009,6 @@ int vo_xv_get_eq(uint32_t xv_port, char *name, int *value) return VO_FALSE; } -/** \brief contains flags changing the execution of the colorkeying code */ -xv_ck_info_t xv_ck_info = { CK_METHOD_MANUALFILL, CK_SRC_CUR }; -unsigned long xv_colorkey; ///< The color used for manual colorkeying. -unsigned int xv_port; ///< The selected Xv port. - /** * \brief Interns the requested atom if it is available. * @@ -2026,20 +2017,21 @@ unsigned int xv_port; ///< The selected Xv port. * \return Returns the atom if available, else None is returned. * */ -static Atom xv_intern_atom_if_exists( char const * atom_name ) +static Atom xv_intern_atom_if_exists(struct vo_x11_state *x11, + char const *atom_name) { XvAttribute * attributes; int attrib_count,i; Atom xv_atom = None; - attributes = XvQueryPortAttributes( mDisplay, xv_port, &attrib_count ); + attributes = XvQueryPortAttributes(x11->display, x11->xv_port, &attrib_count ); if( attributes!=NULL ) { for ( i = 0; i < attrib_count; ++i ) { if ( strcmp(attributes[i].name, atom_name ) == 0 ) { - xv_atom = XInternAtom( mDisplay, atom_name, False ); + xv_atom = XInternAtom(x11->display, atom_name, False ); break; // found what we want, break out } } @@ -2053,12 +2045,13 @@ static Atom xv_intern_atom_if_exists( char const * atom_name ) * \brief Try to enable vsync for xv. * \return Returns -1 if not available, 0 on failure and 1 on success. */ -int vo_xv_enable_vsync(void) +int vo_xv_enable_vsync(struct vo *vo) { - Atom xv_atom = xv_intern_atom_if_exists("XV_SYNC_TO_VBLANK"); + struct vo_x11_state *x11 = vo->x11; + Atom xv_atom = xv_intern_atom_if_exists(x11, "XV_SYNC_TO_VBLANK"); if (xv_atom == None) return -1; - return XvSetPortAttribute(mDisplay, xv_port, xv_atom, 1) == Success; + return XvSetPortAttribute(x11->display, x11->xv_port, xv_atom, 1) == Success; } /** @@ -2072,13 +2065,14 @@ int vo_xv_enable_vsync(void) * \param height [out] The maximum height gets stored here. * */ -void vo_xv_get_max_img_dim( uint32_t * width, uint32_t * height ) +void vo_xv_get_max_img_dim(struct vo *vo, uint32_t * width, uint32_t * height) { + struct vo_x11_state *x11 = vo->x11; XvEncodingInfo * encodings; //unsigned long num_encodings, idx; to int or too long?! unsigned int num_encodings, idx; - XvQueryEncodings( mDisplay, xv_port, &num_encodings, &encodings); + XvQueryEncodings(x11->display, x11->xv_port, &num_encodings, &encodings); if ( encodings ) { @@ -2109,11 +2103,11 @@ void vo_xv_get_max_img_dim( uint32_t * width, uint32_t * height ) * Outputs the content of |ck_handling| as a readable message. * */ -void vo_xv_print_ck_info(void) +static void vo_xv_print_ck_info(struct vo_x11_state *x11) { mp_msg( MSGT_VO, MSGL_V, "[xv common] " ); - switch ( xv_ck_info.method ) + switch ( x11->xv_ck_info.method ) { case CK_METHOD_NONE: mp_msg( MSGT_VO, MSGL_V, "Drawing no colorkey.\n" ); return; @@ -2127,32 +2121,32 @@ void vo_xv_print_ck_info(void) mp_msg( MSGT_VO, MSGL_V, "\n[xv common] " ); - switch ( xv_ck_info.source ) + switch ( x11->xv_ck_info.source ) { case CK_SRC_CUR: mp_msg( MSGT_VO, MSGL_V, "Using colorkey from Xv (0x%06lx).\n", - xv_colorkey ); + x11->xv_colorkey ); break; case CK_SRC_USE: - if ( xv_ck_info.method == CK_METHOD_AUTOPAINT ) + if ( x11->xv_ck_info.method == CK_METHOD_AUTOPAINT ) { mp_msg( MSGT_VO, MSGL_V, "Ignoring colorkey from MPlayer (0x%06lx).\n", - xv_colorkey ); + x11->xv_colorkey ); } else { mp_msg( MSGT_VO, MSGL_V, "Using colorkey from MPlayer (0x%06lx)." " Use -colorkey to change.\n", - xv_colorkey ); + x11->xv_colorkey ); } break; case CK_SRC_SET: mp_msg( MSGT_VO, MSGL_V, "Setting and using colorkey from MPlayer (0x%06lx)." " Use -colorkey to change.\n", - xv_colorkey ); + x11->xv_colorkey ); break; } } @@ -2177,28 +2171,29 @@ void vo_xv_print_ck_info(void) * NOTE: If vo_colorkey has bits set after the first 3 low order bytes * we don't draw anything as this means it was forced to off. */ -int vo_xv_init_colorkey(void) +int vo_xv_init_colorkey(struct vo *vo) { + struct vo_x11_state *x11 = vo->x11; Atom xv_atom; int rez; /* check if colorkeying is needed */ - xv_atom = xv_intern_atom_if_exists( "XV_COLORKEY" ); + xv_atom = xv_intern_atom_if_exists(vo->x11, "XV_COLORKEY"); /* if we have to deal with colorkeying ... */ if( xv_atom != None && !(vo_colorkey & 0xFF000000) ) { /* check if we should use the colorkey specified in vo_colorkey */ - if ( xv_ck_info.source != CK_SRC_CUR ) + if ( x11->xv_ck_info.source != CK_SRC_CUR ) { - xv_colorkey = vo_colorkey; + x11->xv_colorkey = vo_colorkey; /* check if we have to set the colorkey too */ - if ( xv_ck_info.source == CK_SRC_SET ) + if ( x11->xv_ck_info.source == CK_SRC_SET ) { - xv_atom = XInternAtom(mDisplay, "XV_COLORKEY",False); + xv_atom = XInternAtom(x11->display, "XV_COLORKEY",False); - rez = XvSetPortAttribute( mDisplay, xv_port, xv_atom, vo_colorkey ); + rez = XvSetPortAttribute(x11->display, x11->xv_port, xv_atom, vo_colorkey); if ( rez != Success ) { mp_msg( MSGT_VO, MSGL_FATAL, @@ -2211,10 +2206,10 @@ int vo_xv_init_colorkey(void) { int colorkey_ret; - rez=XvGetPortAttribute(mDisplay,xv_port, xv_atom, &colorkey_ret); + rez=XvGetPortAttribute(x11->display,x11->xv_port, xv_atom, &colorkey_ret); if ( rez == Success ) { - xv_colorkey = colorkey_ret; + x11->xv_colorkey = colorkey_ret; } else { @@ -2225,39 +2220,39 @@ int vo_xv_init_colorkey(void) } } - xv_atom = xv_intern_atom_if_exists( "XV_AUTOPAINT_COLORKEY" ); + xv_atom = xv_intern_atom_if_exists(vo->x11, "XV_AUTOPAINT_COLORKEY"); /* should we draw the colorkey ourselves or activate autopainting? */ - if ( xv_ck_info.method == CK_METHOD_AUTOPAINT ) + if ( x11->xv_ck_info.method == CK_METHOD_AUTOPAINT ) { rez = !Success; // reset rez to something different than Success if ( xv_atom != None ) // autopaint is supported { - rez = XvSetPortAttribute( mDisplay, xv_port, xv_atom, 1 ); + rez = XvSetPortAttribute(x11->display, x11->xv_port, xv_atom, 1); } if ( rez != Success ) { // fallback to manual colorkey drawing - xv_ck_info.method = CK_METHOD_MANUALFILL; + x11->xv_ck_info.method = CK_METHOD_MANUALFILL; } } else // disable colorkey autopainting if supported { if ( xv_atom != None ) // we have autopaint attribute { - XvSetPortAttribute( mDisplay, xv_port, xv_atom, 0 ); + XvSetPortAttribute(x11->display, x11->xv_port, xv_atom, 0); } } } else // do no colorkey drawing at all { - xv_ck_info.method = CK_METHOD_NONE; + x11->xv_ck_info.method = CK_METHOD_NONE; } /* end: should we draw colorkey */ /* output information about the current colorkey settings */ - vo_xv_print_ck_info(); + vo_xv_print_ck_info(x11); return 1; // success } @@ -2272,14 +2267,16 @@ int vo_xv_init_colorkey(void) * It doesn't call XFlush. * */ -void vo_xv_draw_colorkey( int32_t x, int32_t y, - int32_t w, int32_t h ) +void vo_xv_draw_colorkey(struct vo *vo, int32_t x, int32_t y, + int32_t w, int32_t h) { - if( xv_ck_info.method == CK_METHOD_MANUALFILL || - xv_ck_info.method == CK_METHOD_BACKGROUND )//less tearing than XClearWindow() + struct MPOpts *opts = vo->opts; + struct vo_x11_state *x11 = vo->x11; + if( x11->xv_ck_info.method == CK_METHOD_MANUALFILL || + x11->xv_ck_info.method == CK_METHOD_BACKGROUND )//less tearing than XClearWindow() { - XSetForeground( mDisplay, vo_gc, xv_colorkey ); - XFillRectangle( mDisplay, vo_window, vo_gc, + XSetForeground(x11->display, x11->vo_gc, x11->xv_colorkey ); + XFillRectangle(x11->display, x11->window, x11->vo_gc, x, y, w, h ); } @@ -2288,24 +2285,24 @@ void vo_xv_draw_colorkey( int32_t x, int32_t y, /* TODO! move this to vo_x11_clearwindow_part() */ if ( vo_fs ) { - XSetForeground( mDisplay, vo_gc, 0 ); + XSetForeground(x11->display, x11->vo_gc, 0 ); /* making non-overlap fills, requires 8 checks instead of 4 */ if ( y > 0 ) - XFillRectangle( mDisplay, vo_window, vo_gc, + XFillRectangle(x11->display, x11->window, x11->vo_gc, 0, 0, - vo_screenwidth, y); + opts->vo_screenwidth, y); if (x > 0) - XFillRectangle( mDisplay, vo_window, vo_gc, + XFillRectangle(x11->display, x11->window, x11->vo_gc, 0, 0, - x, vo_screenheight); - if (x + w < vo_screenwidth) - XFillRectangle( mDisplay, vo_window, vo_gc, + x, opts->vo_screenheight); + if (x + w < opts->vo_screenwidth) + XFillRectangle(x11->display, x11->window, x11->vo_gc, x + w, 0, - vo_screenwidth, vo_screenheight); - if (y + h < vo_screenheight) - XFillRectangle( mDisplay, vo_window, vo_gc, + opts->vo_screenwidth, opts->vo_screenheight); + if (y + h < opts->vo_screenheight) + XFillRectangle(x11->display, x11->window, x11->vo_gc, 0, y + h, - vo_screenwidth, vo_screenheight); + opts->vo_screenwidth, opts->vo_screenheight); } } @@ -2350,19 +2347,20 @@ int xv_test_ckm( void * arg ) * \param str Pointer to the string or NULL * */ -void xv_setup_colorkeyhandling( char const * ck_method_str, - char const * ck_str ) +void xv_setup_colorkeyhandling(struct vo *vo, const char *ck_method_str, + const char *ck_str) { + struct vo_x11_state *x11 = vo->x11; /* check if a valid pointer to the string was passed */ if ( ck_str ) { if ( strncmp( ck_str, "use", 3 ) == 0 ) { - xv_ck_info.source = CK_SRC_USE; + x11->xv_ck_info.source = CK_SRC_USE; } else if ( strncmp( ck_str, "set", 3 ) == 0 ) { - xv_ck_info.source = CK_SRC_SET; + x11->xv_ck_info.source = CK_SRC_SET; } } /* check if a valid pointer to the string was passed */ @@ -2370,17 +2368,30 @@ void xv_setup_colorkeyhandling( char const * ck_method_str, { if ( strncmp( ck_method_str, "bg", 2 ) == 0 ) { - xv_ck_info.method = CK_METHOD_BACKGROUND; + x11->xv_ck_info.method = CK_METHOD_BACKGROUND; } else if ( strncmp( ck_method_str, "man", 3 ) == 0 ) { - xv_ck_info.method = CK_METHOD_MANUALFILL; + x11->xv_ck_info.method = CK_METHOD_MANUALFILL; } else if ( strncmp( ck_method_str, "auto", 4 ) == 0 ) { - xv_ck_info.method = CK_METHOD_AUTOPAINT; + x11->xv_ck_info.method = CK_METHOD_AUTOPAINT; } } } #endif + +struct vo_x11_state *vo_x11_init_state(void) +{ + struct vo_x11_state *s = talloc_ptrtype(NULL, s); + *s = (struct vo_x11_state){ + .xv_ck_info = { CK_METHOD_MANUALFILL, CK_SRC_CUR }, + .olddecor = MWM_DECOR_ALL, + .oldfuncs = MWM_FUNC_MOVE | MWM_FUNC_CLOSE | MWM_FUNC_MINIMIZE | + MWM_FUNC_MAXIMIZE | MWM_FUNC_RESIZE, + .old_gravity = NorthWestGravity, + }; + return s; +} diff --git a/libvo/x11_common.h b/libvo/x11_common.h index c7221d2577..872e84e174 100644 --- a/libvo/x11_common.h +++ b/libvo/x11_common.h @@ -24,6 +24,60 @@ #include "config.h" +struct vo; + +struct vo_x11_state { + Display *display; + Window window; + Window rootwin; + int screen; + int display_is_local; + int depthonscreen; + + GC vo_gc; + + struct xv_ck_info_s { + int method; ///< CK_METHOD_* constants + int source; ///< CK_SRC_* constants + } xv_ck_info; + unsigned long xv_colorkey; + unsigned int xv_port; + + int vo_mouse_autohide; + int wm_type; + int fs_type; + int fs_flip; + + GC f_gc; + XSizeHints vo_hint; + unsigned int mouse_timer; + int mouse_waiting_hide; + int orig_layer; + int old_gravity; + int vo_old_x; + int vo_old_y; + int vo_old_width; + int vo_old_height; + + + unsigned int olddecor; + unsigned int oldfuncs; + XComposeStatus compose_status; + + Atom XA_NET_SUPPORTED; + Atom XA_NET_WM_STATE; + Atom XA_NET_WM_STATE_FULLSCREEN; + Atom XA_NET_WM_STATE_ABOVE; + Atom XA_NET_WM_STATE_STAYS_ON_TOP; + Atom XA_NET_WM_STATE_BELOW; + Atom XA_NET_WM_PID; + Atom XA_WIN_PROTOCOLS; + Atom XA_WIN_LAYER; + Atom XA_WIN_HINTS; + Atom XAWM_PROTOCOLS; + Atom XAWM_DELETE_WINDOW; +}; + #if defined(CONFIG_GL) || defined(CONFIG_X11) || defined(CONFIG_XV) #define X11_FULLSCREEN 1 #endif @@ -51,67 +105,46 @@ extern int vo_fs_type; extern char** vo_fstype_list; extern char *mDisplayName; -extern Display *mDisplay; extern Window mRootWin; extern int mScreen; extern int mLocalDisplay; -extern int vo_mouse_autohide; - -int vo_init( void ); -void vo_uninit( void ); -void vo_hidecursor ( Display* , Window ); -void vo_showcursor( Display *disp, Window win ); -void vo_x11_decoration( Display * vo_Display,Window w,int d ); -void vo_x11_classhint( Display * display,Window window,char *name ); -void vo_x11_nofs_sizepos(int x, int y, int width, int height); -void vo_x11_sizehint( int x, int y, int width, int height, int max ); -int vo_x11_check_events(Display *mydisplay); +struct vo_x11_state *vo_x11_init_state(void); +int vo_init(struct vo *vo); +void vo_uninit(struct vo_x11_state *x11); +void vo_x11_decoration(struct vo *vo, int d ); +void vo_x11_classhint(struct vo *vo, Window window, char *name); +void vo_x11_sizehint(struct vo *vo, int x, int y, int width, int height, int max); +int vo_x11_check_events(struct vo *vo); void vo_x11_selectinput_witherr(Display *display, Window w, long event_mask); -int vo_x11_update_geometry(void); -void vo_x11_fullscreen( void ); -void vo_x11_setlayer( Display * mDisplay,Window vo_window,int layer ); -void vo_x11_uninit(void); -Colormap vo_x11_create_colormap(XVisualInfo *vinfo); -uint32_t vo_x11_set_equalizer(char *name, int value); +void vo_x11_fullscreen(struct vo *vo); +int vo_x11_update_geometry(struct vo *vo); +void vo_x11_setlayer(struct vo *vo, Window vo_window, int layer); +void vo_x11_uninit(struct vo *vo); +Colormap vo_x11_create_colormap(struct vo *vo, XVisualInfo *vinfo); +uint32_t vo_x11_set_equalizer(struct vo *vo, char *name, int value); uint32_t vo_x11_get_equalizer(char *name, int *value); void fstype_help(void); -Window vo_x11_create_smooth_window( Display *mDisplay, Window mRoot, - Visual *vis, int x, int y, unsigned int width, unsigned int height, - int depth, Colormap col_map); -void vo_x11_create_vo_window(XVisualInfo *vis, int x, int y, - unsigned int width, unsigned int height, int flags, +void vo_x11_create_vo_window(struct vo *vo, XVisualInfo *vis, + int x, int y, unsigned int width, unsigned int height, int flags, Colormap col_map, const char *classname, const char *title); -void vo_x11_clearwindow_part(Display *mDisplay, Window vo_window, +void vo_x11_clearwindow_part(struct vo *vo, Window vo_window, int img_width, int img_height, int use_fs); -void vo_x11_clearwindow( Display *mDisplay, Window vo_window ); -void vo_x11_ontop(void); -void vo_x11_border(void); -void vo_x11_ewmh_fullscreen( int action ); +void vo_x11_clearwindow(struct vo *vo, Window vo_window); +void vo_x11_ontop(struct vo *vo); +void vo_x11_border(struct vo *vo); +void vo_x11_ewmh_fullscreen(struct vo_x11_state *x11, int action); #endif -extern Window vo_window; -extern GC vo_gc; -extern XSizeHints vo_hint; - -#ifdef CONFIG_XV -//XvPortID xv_port; -extern unsigned int xv_port; +int vo_xv_set_eq(struct vo *vo, uint32_t xv_port, char * name, int value); +int vo_xv_get_eq(struct vo *vo, uint32_t xv_port, char * name, int *value); -int vo_xv_set_eq(uint32_t xv_port, char * name, int value); -int vo_xv_get_eq(uint32_t xv_port, char * name, int *value); +int vo_xv_enable_vsync(struct vo *vo); -int vo_xv_enable_vsync(void); - -void vo_xv_get_max_img_dim( uint32_t * width, uint32_t * height ); +void vo_xv_get_max_img_dim(struct vo *vo, uint32_t * width, uint32_t * height); /*** colorkey handling ***/ -typedef struct xv_ck_info_s -{ - int method; ///< CK_METHOD_* constants - int source; ///< CK_SRC_* constants -} xv_ck_info_t; #define CK_METHOD_NONE 0 ///< no colorkey drawing #define CK_METHOD_BACKGROUND 1 ///< set colorkey as window background @@ -121,31 +154,65 @@ typedef struct xv_ck_info_s #define CK_SRC_SET 1 ///< use and set specified / default colorkey #define CK_SRC_CUR 2 ///< use current colorkey ( get it from xv ) -extern xv_ck_info_t xv_ck_info; -extern unsigned long xv_colorkey; - -int vo_xv_init_colorkey(void); -void vo_xv_draw_colorkey(int32_t x, int32_t y, int32_t w, int32_t h); -void xv_setup_colorkeyhandling(char const * ck_method_str, char const * ck_str); +int vo_xv_init_colorkey(struct vo *vo); +void vo_xv_draw_colorkey(struct vo *vo, int32_t x, int32_t y, int32_t w, int32_t h); +void xv_setup_colorkeyhandling(struct vo *vo, const char *ck_method_str, const char *ck_str); /*** test functions for common suboptions ***/ int xv_test_ck( void * arg ); int xv_test_ckm( void * arg ); -#endif - -void vo_setwindow( Window w,GC g ); -void vo_x11_putkey(int key); -void saver_off( Display * ); -void saver_on( Display * ); +void vo_x11_putkey(struct vo *vo, int key); #ifdef CONFIG_XF86VM -void vo_vm_switch(void); -void vo_vm_close(void); +void vo_vm_switch(struct vo *vo); +void vo_vm_close(struct vo *vo); #endif -void update_xinerama_info(void); +void update_xinerama_info(struct vo *vo); int vo_find_depth_from_visuals(Display *dpy, int screen, Visual **visual_return); +void xscreensaver_heartbeat(struct vo_x11_state *x11); + +// Old VOs use incompatible function calls, translate them to new +// prototypes +#ifdef IS_OLD_VO +#define vo_x11_create_vo_window(...) vo_x11_create_vo_window(global_vo, __VA_ARGS__) +#define vo_x11_fullscreen() vo_x11_fullscreen(global_vo) +#define vo_x11_update_geometry() vo_x11_update_geometry(global_vo) +#define vo_x11_ontop() vo_x11_ontop(global_vo) +#define vo_init() vo_init(global_vo) +#define vo_x11_ewmh_fullscreen(action) vo_x11_ewmh_fullscreen(global_vo->x11->display, action) +#define update_xinerama_info() update_xinerama_info(global_vo) +#define vo_x11_uninit() vo_x11_uninit(global_vo) +#define vo_x11_check_events(display) vo_x11_check_events(global_vo) +#define vo_x11_sizehint(...) vo_x11_sizehint(global_vo, __VA_ARGS__) +#define vo_vm_switch() vo_vm_switch(global_vo) +#define vo_x11_create_colormap(vinfo) vo_x11_create_colormap(global_vo, vinfo) +#define vo_x11_set_equalizer(...) vo_x11_set_equalizer(global_vo, __VA_ARGS__) +#define vo_xv_set_eq(...) vo_xv_set_eq(global_vo, __VA_ARGS__) +#define vo_xv_get_eq(...) vo_xv_get_eq(global_vo, __VA_ARGS__) +#define vo_xv_enable_vsync() vo_xv_enable_vsync(global_vo) +#define vo_xv_get_max_img_dim(...) vo_xv_get_max_img_dim(global_vo, __VA_ARGS__) +#define vo_xv_init_colorkey() vo_xv_init_colorkey(global_vo) +#define vo_xv_draw_colorkey(...) vo_xv_draw_colorkey(global_vo, __VA_ARGS__) +#define vo_x11_clearwindow_part(display, ...) vo_x11_clearwindow_part(global_vo, __VA_ARGS__) +#define vo_vm_close() vo_vm_close(global_vo) +#define vo_x11_clearwindow(display, window) vo_x11_clearwindow(global_vo, window) +#define vo_x11_classhint(display, window, name) vo_x11_classhint(global_vo, window, name) +#define vo_x11_setlayer(display, window, layer) vo_x11_setlayer(global_vo, window, layer) +#define xv_setup_colorkeyhandling(a, b) xv_setup_colorkeyhandling(global_vo, a, b) + +#define mDisplay global_vo->x11->display +#define vo_depthonscreen global_vo->x11->depthonscreen +#define vo_window global_vo->x11->window +#define xv_ck_info global_vo->x11->xv_ck_info +#define xv_colorkey global_vo->x11->xv_colorkey +#define xv_port global_vo->x11->xv_port +#define vo_gc global_vo->x11->vo_gc +#define mRootWin global_vo->x11->rootwin +#define mScreen global_vo->x11->screen +#define mLocalDisplay global_vo->x11->display_is_local +#endif #endif /* MPLAYER_X11_COMMON_H */ diff --git a/loader/qtx/qtxsdk/components.h b/loader/qtx/qtxsdk/components.h index e1415a94cd..e28bf953b4 100644 --- a/loader/qtx/qtxsdk/components.h +++ b/loader/qtx/qtxsdk/components.h @@ -656,6 +656,7 @@ static inline void dump_ImageDescription(void* xxx){ printf("=========================================================\n"); } +#if 0 static inline void dump_Rect(char* title,Rect *r){ printf("%s: %d;%d - %d;%d\n",title, (int)r->top,(int)r->left,(int)r->bottom,(int)r->right); @@ -743,5 +744,6 @@ static inline void dump_CodecDecompressParams(void* xxx){ } +#endif #endif /* MPLAYER_COMPONENTS_H */ diff --git a/m_config.c b/m_config.c index 263144813e..2cbe777d68 100644 --- a/m_config.c +++ b/m_config.c @@ -8,6 +8,7 @@ #include <stdio.h> #include <errno.h> #include <string.h> +#include "talloc.h" #ifdef MP_DEBUG #include <assert.h> #endif @@ -34,12 +35,33 @@ m_config_add_option(m_config_t *config, const m_option_t *arg, const char* prefi static int list_options(m_option_t *opt, char* name, char *param); -m_config_t* -m_config_new(void) { +static void m_option_save(const m_config_t *config, const m_option_t *opt, + void *dst) +{ + if (opt->type->save) { + void *src = opt->new ? (char*)config->optstruct + opt->offset : opt->p; + opt->type->save(opt, dst, src); + } +} + +static void m_option_set(const m_config_t *config, const m_option_t *opt, + void *src) +{ + if (opt->type->set) { + void *dst = opt->new ? (char*)config->optstruct + opt->offset : opt->p; + opt->type->set(opt, dst, src); + } +} + + + +m_config_t *m_config_new(void *optstruct, + int includefunc(m_option_t *conf, char *filename)) +{ m_config_t* config; static int initialized = 0; static m_option_type_t profile_opt_type; - static m_option_t ref_opts[] = { + static const m_option_t ref_opts[] = { { "profile", NULL, &profile_opt_type, CONF_NOSAVE, 0, 0, NULL }, { "show-profile", show_profile, CONF_TYPE_PRINT_FUNC, CONF_NOCFG, 0, 0, NULL }, { "list-options", list_options, CONF_TYPE_PRINT_FUNC, CONF_NOCFG, 0, 0, NULL }, @@ -47,7 +69,7 @@ m_config_new(void) { }; int i; - config = calloc(1,sizeof(m_config_t)); + config = talloc_zero(NULL, m_config_t); config->lvl = 1; // 0 Is the defaults if(!initialized) { initialized = 1; @@ -55,56 +77,32 @@ m_config_new(void) { profile_opt_type.parse = parse_profile; profile_opt_type.set = set_profile; } - config->self_opts = malloc(sizeof(ref_opts)); - memcpy(config->self_opts,ref_opts,sizeof(ref_opts)); - for(i = 0 ; config->self_opts[i].name ; i++) - config->self_opts[i].priv = config; - m_config_register_options(config,config->self_opts); - + m_option_t *self_opts = talloc_memdup(config, ref_opts, sizeof(ref_opts)); + for (i = 0; self_opts[i].name; i++) + self_opts[i].priv = config; + m_config_register_options(config, self_opts); + if (includefunc) { + struct m_option *p = talloc_ptrtype(config, p); + *p = (struct m_option){"include", includefunc, CONF_TYPE_FUNC_PARAM, + CONF_NOSAVE, 0, 0, config}; + m_config_add_option(config, p, NULL); + } + config->optstruct = optstruct; + return config; } -void -m_config_free(m_config_t* config) { - m_config_option_t *i = config->opts, *ct; - m_config_save_slot_t *sl,*st; - m_profile_t *p,*pn; - int j; - -#ifdef MP_DEBUG - assert(config != NULL); -#endif - - while(i) { - if (i->flags & M_CFG_OPT_ALIAS) - sl = NULL; - else - sl = i->slots; - while(sl) { - m_option_free(i->opt,sl->data); - st = sl->prev; - free(sl); - sl = st; - } - if(i->name != i->opt->name) - free(i->name); - ct = i->next; - free(i); - i = ct; - } - for(p = config->profiles ; p ; p = pn) { - pn = p->next; - free(p->name); - if(p->desc) free(p->desc); - for(j = 0 ; j < p->num_opts ; j++) { - free(p->opts[2*j]); - if(p->opts[2*j+1]) free(p->opts[2*j+1]); +void m_config_free(m_config_t* config) +{ + m_config_option_t *opt; + for (opt = config->opts; opt; opt = opt->next) { + if (opt->flags & M_CFG_OPT_ALIAS) + continue; + m_config_save_slot_t *sl; + for (sl = opt->slots; sl; sl = sl->prev) + m_option_free(opt->opt, sl->data); } - free(p->opts); - free(p); - } - free(config->self_opts); - free(config); + talloc_free(config); } void @@ -130,10 +128,11 @@ m_config_push(m_config_t* config) { continue; // Update the current status - m_option_save(co->opt,co->slots->data,co->opt->p); + m_option_save(config, co->opt, co->slots->data); // Allocate a new slot - slot = calloc(1,sizeof(m_config_save_slot_t) + co->opt->type->size); + slot = talloc_zero_size(co, sizeof(m_config_save_slot_t) + + co->opt->type->size); slot->lvl = config->lvl; slot->prev = co->slots; co->slots = slot; @@ -170,11 +169,11 @@ m_config_pop(m_config_t* config) { m_option_free(co->opt,co->slots->data); slot = co->slots; co->slots = slot->prev; - free(slot); + talloc_free(slot); pop++; } if(pop) // We removed some ctx -> set the previous value - m_option_set(co->opt,co->opt->p,co->slots->data); + m_option_set(config, co->opt, co->slots->data); } config->lvl--; @@ -193,14 +192,12 @@ m_config_add_option(m_config_t *config, const m_option_t *arg, const char* prefi #endif // Allocate a new entry for this option - co = calloc(1,sizeof(m_config_option_t) + arg->type->size); + co = talloc_zero_size(config, sizeof(m_config_option_t) + arg->type->size); co->opt = arg; // Fill in the full name if(prefix && strlen(prefix) > 0) { - int l = strlen(prefix) + 1 + strlen(arg->name) + 1; - co->name = malloc(l); - sprintf(co->name,"%s:%s",prefix,arg->name); + co->name = talloc_asprintf(co, "%s:%s", prefix, arg->name); } else co->name = arg->name; @@ -214,9 +211,11 @@ m_config_add_option(m_config_t *config, const m_option_t *arg, const char* prefi } else { m_config_option_t *i; // Check if there is already an option pointing to this address - if(arg->p) { + if(arg->p || arg->new && arg->offset >= 0) { for(i = config->opts ; i ; i = i->next ) { - if(i->opt->p == arg->p) { // So we don't save the same vars more than 1 time + if (arg->new ? (i->opt->new && i->opt->offset == arg->offset) + : (!i->opt->new && i->opt->p == arg->p)) { + // So we don't save the same vars more than 1 time co->slots = i->slots; co->flags |= M_CFG_OPT_ALIAS; break; @@ -224,22 +223,28 @@ m_config_add_option(m_config_t *config, const m_option_t *arg, const char* prefi } } if(!(co->flags & M_CFG_OPT_ALIAS)) { - // Allocate a slot for the defaults - sl = calloc(1,sizeof(m_config_save_slot_t) + arg->type->size); - m_option_save(arg,sl->data,(void**)arg->p); - // Hack to avoid too much trouble with dynamically allocated data : - // We always use a dynamic version - if((arg->type->flags & M_OPT_TYPE_DYNAMIC) && arg->p && (*(void**)arg->p)) { - *(void**)arg->p = NULL; - m_option_set(arg,arg->p,sl->data); + // Allocate a slot for the defaults + sl = talloc_zero_size(co, sizeof(m_config_save_slot_t) + + arg->type->size); + m_option_save(config, arg, sl->data); + // Hack to avoid too much trouble with dynamically allocated data : + // We always use a dynamic version + if ((arg->type->flags & M_OPT_TYPE_DYNAMIC)) { + char **hackptr = arg->new ? (char*)config->optstruct + arg->offset + : arg->p; + if (hackptr && *hackptr) { + *hackptr = NULL; + m_option_set(config, arg, sl->data); + } + } + sl->lvl = 0; + sl->prev = NULL; + co->slots = talloc_zero_size(co, sizeof(m_config_save_slot_t) + + arg->type->size); + co->slots->prev = sl; + co->slots->lvl = config->lvl; + m_option_copy(co->opt, co->slots->data, sl->data); } - sl->lvl = 0; - sl->prev = NULL; - co->slots = calloc(1,sizeof(m_config_save_slot_t) + arg->type->size); - co->slots->prev = sl; - co->slots->lvl = config->lvl; - m_option_copy(co->opt,co->slots->data,sl->data); - } // !M_OPT_ALIAS } co->next = config->opts; config->opts = co; @@ -355,7 +360,7 @@ m_config_parse_option(m_config_t *config, char* arg, char* param,int set) { return r; // Set the option if(set) { - m_option_set(co->opt,co->opt->p,co->slots->data); + m_option_set(config, co->opt, co->slots->data); co->flags |= M_CFG_OPT_SET; } @@ -398,20 +403,6 @@ m_config_get_option(m_config_t *config, char* arg) { return NULL; } -const void* -m_config_get_option_ptr(m_config_t *config, char* arg) { - const m_option_t* conf; - -#ifdef MP_DEBUG - assert(config != NULL); - assert(arg != NULL); -#endif - - conf = m_config_get_option(config,arg); - if(!conf) return NULL; - return conf->p; -} - void m_config_print_option_list(m_config_t *config) { char min[50],max[50]; @@ -457,8 +448,8 @@ m_profile_t* m_config_add_profile(m_config_t* config, char* name) { m_profile_t* p = m_config_get_profile(config,name); if(p) return p; - p = calloc(1,sizeof(m_profile_t)); - p->name = strdup(name); + p = talloc_zero(config, m_profile_t); + p->name = talloc_strdup(p, name); p->next = config->profiles; config->profiles = p; return p; @@ -466,8 +457,8 @@ m_config_add_profile(m_config_t* config, char* name) { void m_profile_set_desc(m_profile_t* p, char* desc) { - if(p->desc) free(p->desc); - p->desc = desc ? strdup(desc) : NULL; + talloc_free(p->desc); + p->desc = talloc_strdup(p, desc); } int @@ -475,10 +466,9 @@ m_config_set_profile_option(m_config_t* config, m_profile_t* p, char* name, char* val) { int i = m_config_check_option(config,name,val); if(i < 0) return i; - if(p->opts) p->opts = realloc(p->opts,2*(p->num_opts+2)*sizeof(char*)); - else p->opts = malloc(2*(p->num_opts+2)*sizeof(char*)); - p->opts[p->num_opts*2] = strdup(name); - p->opts[p->num_opts*2+1] = val ? strdup(val) : NULL; + p->opts = talloc_realloc(p, p->opts, char *, 2*(p->num_opts+2)); + p->opts[p->num_opts*2] = talloc_strdup(p, name); + p->opts[p->num_opts*2+1] = talloc_strdup(p, val); p->num_opts++; p->opts[p->num_opts*2] = p->opts[p->num_opts*2+1] = NULL; return 1; diff --git a/m_config.h b/m_config.h index e6b8bc9247..60064e8771 100644 --- a/m_config.h +++ b/m_config.h @@ -76,8 +76,8 @@ typedef struct m_config { m_profile_t* profiles; /// Depth when recursively including profiles. int profile_depth; - /// Options defined by the config itself. - struct m_option* self_opts; + + void *optstruct; // struct mpopts or other } m_config_t; /// \defgroup ConfigOptionFlags Config option flags @@ -96,7 +96,8 @@ typedef struct m_config { /** \ingroup Config */ m_config_t* -m_config_new(void); +m_config_new(void *optstruct, + int includefunc(struct m_option *conf, char *filename)); /// Free a config object. void diff --git a/m_option.c b/m_option.c index 1991bb4a56..e3e338808c 100644 --- a/m_option.c +++ b/m_option.c @@ -762,8 +762,6 @@ static void set_func_param(const m_option_t* opt, void* dst, void* src) { if(!s) return; - // Revert if needed - if(opt->priv) ((m_opt_default_func_t)opt->priv)(opt,opt->name); for( ; s != NULL ; s = s->next) ((m_opt_func_param_t) opt->p)(opt,s->param); } @@ -811,18 +809,12 @@ const m_option_type_t m_option_type_func_full = { /////////////// Func #undef VAL -#define VAL(x) (*(int*)(x)) static int parse_func(const m_option_t* opt,const char *name, char *param, void* dst, int src) { - if(dst) - VAL(dst) += 1; return 0; } static void set_func(const m_option_t* opt,void* dst, void* src) { - int i; - if(opt->priv) ((m_opt_default_func_t)opt->priv)(opt,opt->name); - for(i = 0 ; i < VAL(src) ; i++) ((m_opt_func_t) opt->p)(opt); } diff --git a/m_option.h b/m_option.h index a54aac540f..0cf55fbaf1 100644 --- a/m_option.h +++ b/m_option.h @@ -2,6 +2,7 @@ #define MPLAYER_M_OPTION_H #include <string.h> +#include <stddef.h> /// \defgroup Options /// m_option allows to parse, print and copy data of various types. @@ -282,6 +283,10 @@ struct m_option { * Passing a 'default func' is still valid for all func based option types. */ void* priv; + + int new; + + int offset; }; @@ -476,20 +481,6 @@ m_option_print(const m_option_t* opt, const void* val_ptr) { return (char*)-1; } -/// Helper around \ref m_option_type::save. -inline static void -m_option_save(const m_option_t* opt,void* dst, void* src) { - if(opt->type->save) - opt->type->save(opt,dst,src); -} - -/// Helper around \ref m_option_type::set. -inline static void -m_option_set(const m_option_t* opt,void* dst, void* src) { - if(opt->type->set) - opt->type->set(opt,dst,src); -} - /// Helper around \ref m_option_type::copy. inline static void m_option_copy(const m_option_t* opt,void* dst, void* src) { @@ -508,4 +499,14 @@ m_option_free(const m_option_t* opt,void* dst) { /*@}*/ +#define OPT_FLAG_ON(optname, varname, flags) {optname, NULL, &m_option_type_flag, flags, 0, 1, NULL, 1, offsetof(struct MPOpts, varname)} +#define OPT_FLAG_OFF(optname, varname, flags) {optname, NULL, &m_option_type_flag, flags, 1, 0, NULL, 1, offsetof(struct MPOpts, varname)} +#define OPT_FLAG_CONSTANTS(optname, varname, flags, offvalue, value) {optname, NULL, &m_option_type_flag, flags, offvalue, value, NULL, 1, offsetof(struct MPOpts, varname)} +#define OPT_STRINGLIST(optname, varname, flags) {optname, NULL, &m_option_type_string_list, flags, 0, 0, NULL, 1, offsetof(struct MPOpts, varname)} +#define OPT_INT(optname, varname, flags) {optname, NULL, &m_option_type_int, flags, 0, 0, NULL, 1, offsetof(struct MPOpts, varname)} +#define OPT_INTRANGE(optname, varname, flags, min, max) {optname, NULL, &m_option_type_int, (flags)|CONF_RANGE, min, max, NULL, 1, offsetof(struct MPOpts, varname)} +#define OPT_FLOATRANGE(optname, varname, flags, min, max) {optname, NULL, &m_option_type_float, (flags)|CONF_RANGE, min, max, NULL, 1, offsetof(struct MPOpts, varname)} +#define OPT_STRING(optname, varname, flags) {optname, NULL, &m_option_type_string, flags, 0, 0, NULL, 1, offsetof(struct MPOpts, varname)} +#define OPT_SETTINGSLIST(optname, varname, flags, objlist) {optname, NULL, &m_option_type_obj_settings_list, flags, 0, 0, objlist, 1, offsetof(struct MPOpts, varname)} + #endif /* MPLAYER_M_OPTION_H */ diff --git a/mencoder.c b/mencoder.c index 2d9d037e22..1661722679 100644 --- a/mencoder.c +++ b/mencoder.c @@ -86,9 +86,15 @@ #endif #include "libmpcodecs/ae.h" +#include "options.h" +#include "defaultopts.h" + +MPOpts opts; +struct osd_state *osd; + +const int under_mencoder = 1; int vo_doublebuffering=0; int vo_directrendering=0; -int vo_config_count=1; int forced_subs_only=0; //-------------------------- @@ -104,9 +110,6 @@ float stream_cache_seek_min_percent=50.0; #define cache_fill_status 0 #endif -int audio_id=-1; -int video_id=-1; -int dvdsub_id=-2; int vobsub_id=-1; char* audio_lang=NULL; char* dvdsub_lang=NULL; @@ -156,7 +159,6 @@ static int audio_density=2; double force_fps=0; static double force_ofps=0; // set to 24 for inverse telecine static int skip_limit=-1; -float playback_speed=1.0; static int force_srate=0; static int audio_output_format=0; @@ -203,18 +205,19 @@ char *info_sourceform=NULL; char *info_comment=NULL; // Needed by libmpcodecs vf_vo.c -int config_video_out(const vo_functions_t *vo, uint32_t width, uint32_t height, - uint32_t d_width, uint32_t d_height, uint32_t flags, - char *title, uint32_t format) { - return 1; -} -// Needed by libmpdemux. -int mp_input_check_interrupt(int time) { - usec_sleep(time); - return 0; -} +int vo_config(struct vo *vo, uint32_t width, uint32_t height, + uint32_t d_width, uint32_t d_height, uint32_t flags, + char *title, uint32_t format) { abort(); } +int vo_control(struct vo *vo, uint32_t request, void *data) { abort(); } +int vo_draw_frame(struct vo *vo, uint8_t *src[]) { abort(); } +int vo_draw_slice(struct vo *vo, uint8_t *src[], int stride[], int w, int h, int x, int y) { abort(); } +void vo_draw_osd(struct vo *vo, struct osd_state *osd) { abort(); } +void vo_flip_page(struct vo *vo) { abort(); } +void vo_check_events(struct vo *vo) { abort(); } + // Needed by getch2 -void mplayer_put_key(int code) +struct mp_fifo; +void mplayer_put_key(struct mp_fifo *fifo, int code) { } @@ -404,12 +407,11 @@ ao_data_t ao_data = {0,0,0,0,OUTBURST,-1,0}; audio_encoding_params_t aparams; audio_encoder_t *aencoder = NULL; -user_correct_pts = 0; - mp_msg_init(); // Create the config context and register the options - mconfig = m_config_new(); + set_default_mencoder_options(&opts); + mconfig = m_config_new(&opts, cfg_include); m_config_register_options(mconfig,mencoder_opts); // Preparse the command line @@ -471,7 +473,7 @@ if(!codecs_file || !parse_codec_cfg(codecs_file)){ if (frameno_filename) { stream2=open_stream(frameno_filename,0,&i); if(stream2){ - demuxer2=demux_open(stream2,DEMUXER_TYPE_AVI,-1,-1,-2,NULL); + demuxer2=demux_open(&opts, stream2,DEMUXER_TYPE_AVI,-1,-1,-2,NULL); if(demuxer2) mp_msg(MSGT_MENCODER, MSGL_INFO, MSGTR_UsingPass3ControlFile, frameno_filename); else mp_msg(MSGT_DEMUXER,MSGL_ERR,MSGTR_FormatNotRecognized); } @@ -504,7 +506,7 @@ if (frameno_filename) { } #endif - vo_init_osd(); + osd = osd_create(); /* HACK, for some weird reason, push() has to be called twice, otherwise options are not saved correctly */ @@ -529,15 +531,15 @@ play_next_file: #ifdef CONFIG_DVDREAD if(stream->type==STREAMTYPE_DVD){ - if(audio_lang && audio_id==-1) audio_id=dvd_aid_from_lang(stream,audio_lang); - if(dvdsub_lang && dvdsub_id==-2) dvdsub_id=dvd_sid_from_lang(stream,dvdsub_lang); + if(audio_lang && opts.audio_id==-1) opts.audio_id=dvd_aid_from_lang(stream,audio_lang); + if(dvdsub_lang && opts.sub_id==-2) opts.sub_id=dvd_sid_from_lang(stream,dvdsub_lang); } #endif #ifdef CONFIG_DVDNAV if(stream->type==STREAMTYPE_DVDNAV){ - if(audio_lang && audio_id==-1) audio_id=mp_dvdnav_aid_from_lang(stream,audio_lang); - if(dvdsub_lang && dvdsub_id==-2) dvdsub_id=mp_dvdnav_sid_from_lang(stream,dvdsub_lang); + if(audio_lang && opts.audio_id==-1) opts.audio_id=mp_dvdnav_aid_from_lang(stream,audio_lang); + if(dvdsub_lang && opts.sub_id==-2) opts.sub_id=mp_dvdnav_sid_from_lang(stream,dvdsub_lang); } #endif @@ -545,27 +547,27 @@ if(stream->type==STREAMTYPE_DVDNAV){ if(stream_cache_size>0) stream_enable_cache(stream,stream_cache_size*1024,0,0); - if(demuxer2) audio_id=-2; /* do NOT read audio packets... */ + if(demuxer2) opts.audio_id=-2; /* do NOT read audio packets... */ - //demuxer=demux_open(stream,file_format,video_id,audio_id,dvdsub_id); - demuxer=demux_open(stream,file_format,audio_id,video_id,dvdsub_id,filename); + //demuxer=demux_open(stream,file_format,opts.video_id,opts.audio_id,opts.sub_id); + demuxer=demux_open(&opts, stream,file_format,opts.audio_id,opts.video_id,opts.sub_id,filename); if(!demuxer){ mp_msg(MSGT_DEMUXER, MSGL_FATAL, MSGTR_FormatNotRecognized); mp_msg(MSGT_DEMUXER, MSGL_FATAL, MSGTR_CannotOpenDemuxer); mencoder_exit(1,NULL); } - select_audio(demuxer, audio_id, audio_lang); + select_audio(demuxer, opts.audio_id, audio_lang); - if (dvdsub_id < 0 && dvdsub_lang) - dvdsub_id = demuxer_sub_track_by_lang(demuxer, dvdsub_lang); + if (opts.sub_id < 0 && dvdsub_lang) + opts.sub_id = demuxer_sub_track_by_lang(demuxer, dvdsub_lang); - if (dvdsub_id < 0) - dvdsub_id = demuxer_default_sub_track(demuxer); + if (opts.sub_id < 0) + opts.sub_id = demuxer_default_sub_track(demuxer); for (i = 0; i < MAX_S_STREAMS; i++) { sh_sub_t *sh = demuxer->s_streams[i]; - if (sh && sh->sid == dvdsub_id) { + if (sh && sh->sid == opts.sub_id) { demuxer->sub->id = i; demuxer->sub->sh = sh; break; @@ -607,7 +609,7 @@ sh_video=d_video->sh; } if(sh_audio && out_audio_codec<0){ - if(audio_id==-2) + if(opts.audio_id==-2) mp_msg(MSGT_MENCODER,MSGL_ERR,MSGTR_DemuxerDoesntSupportNosound); mp_msg(MSGT_MENCODER,MSGL_FATAL,MSGTR_NoAudioEncoderSelected); mencoder_exit(1,NULL); @@ -617,7 +619,7 @@ sh_video=d_video->sh; mencoder_exit(1,NULL); } -if(sh_audio && (out_audio_codec || seek_to_sec || !sh_audio->wf || playback_speed != 1.0)){ +if(sh_audio && (out_audio_codec || seek_to_sec || !sh_audio->wf || opts.playback_speed != 1.0)){ // Go through the codec.conf and find the best codec... mp_msg(MSGT_CPLAYER,MSGL_INFO,"==========================================================================\n"); if(!init_best_audio_codec(sh_audio,audio_codec_list,audio_fm_list)){ @@ -628,12 +630,12 @@ if(sh_audio && (out_audio_codec || seek_to_sec || !sh_audio->wf || playback_spee if (sh_audio) { new_srate = sh_audio->samplerate; - if (playback_speed != 1.0) { - new_srate *= playback_speed; + if (opts.playback_speed != 1.0) { + new_srate *= opts.playback_speed; // limits are taken from libaf/af_resample.c if (new_srate < 8000) new_srate = 8000; if (new_srate > 192000) new_srate = 192000; - playback_speed = (float)new_srate / (float)sh_audio->samplerate; + opts.playback_speed = (float)new_srate / (float)sh_audio->samplerate; } } @@ -663,7 +665,7 @@ if (!curfile) { // curfile is non zero when a second file is opened if (vobsub_out) { unsigned int palette[16], width, height; unsigned char tmp[3] = { 0, 0, 0 }; - if (spudec_ifo && vobsub_parse_ifo(NULL,spudec_ifo, palette, &width, &height, 1, dvdsub_id, tmp) >= 0) + if (spudec_ifo && vobsub_parse_ifo(NULL,spudec_ifo, palette, &width, &height, 1, opts.sub_id, tmp) >= 0) vobsub_writer = vobsub_out_open(vobsub_out, palette, sh_video->disp_w, sh_video->disp_h, vobsub_out_id?vobsub_out_id:(char *)tmp, vobsub_out_index); #ifdef CONFIG_DVDREAD @@ -673,7 +675,7 @@ if (vobsub_out) { int i; dvd_priv_t *dvd = (dvd_priv_t*)stream->priv; for (i = 0; i < dvd->nr_of_subtitles; ++i) - if (dvd->subtitles[i].id == dvdsub_id) { + if (dvd->subtitles[i].id == opts.sub_id) { tmp[0] = (dvd->subtitles[i].language >> 8) & 0xff; tmp[1] = dvd->subtitles[i].language & 0xff; tmp[2] = 0; @@ -730,14 +732,14 @@ mux_v->source=sh_video; mux_v->h.dwSampleSize=0; // VBR #ifdef CONFIG_LIBAVCODEC { - double fps = force_ofps?force_ofps:sh_video->fps*playback_speed; + double fps = force_ofps?force_ofps:sh_video->fps*opts.playback_speed; AVRational q= av_d2q(fps, fps*1001+2); mux_v->h.dwScale= q.den; mux_v->h.dwRate = q.num; } #else mux_v->h.dwScale=10000; -mux_v->h.dwRate=mux_v->h.dwScale*(force_ofps?force_ofps:sh_video->fps*playback_speed); +mux_v->h.dwRate=mux_v->h.dwScale*(force_ofps?force_ofps:sh_video->fps*opts.playback_speed); #endif mux_v->codec=out_video_codec; @@ -811,21 +813,21 @@ default: { if (!ve) { switch(mux_v->codec){ case VCODEC_LIBAVCODEC: - sh_video->vfilter=vf_open_encoder(NULL,"lavc",(char *)mux_v); break; + sh_video->vfilter=vf_open_encoder(&opts, NULL,"lavc",(char *)mux_v); break; case VCODEC_RAW: - sh_video->vfilter=vf_open_encoder(NULL,"raw",(char *)mux_v); break; + sh_video->vfilter=vf_open_encoder(&opts, NULL,"raw",(char *)mux_v); break; case VCODEC_VFW: - sh_video->vfilter=vf_open_encoder(NULL,"vfw",(char *)mux_v); break; + sh_video->vfilter=vf_open_encoder(&opts, NULL,"vfw",(char *)mux_v); break; case VCODEC_LIBDV: - sh_video->vfilter=vf_open_encoder(NULL,"libdv",(char *)mux_v); break; + sh_video->vfilter=vf_open_encoder(&opts, NULL,"libdv",(char *)mux_v); break; case VCODEC_XVID: - sh_video->vfilter=vf_open_encoder(NULL,"xvid",(char *)mux_v); break; + sh_video->vfilter=vf_open_encoder(&opts, NULL,"xvid",(char *)mux_v); break; case VCODEC_QTVIDEO: - sh_video->vfilter=vf_open_encoder(NULL,"qtvideo",(char *)mux_v); break; + sh_video->vfilter=vf_open_encoder(&opts, NULL,"qtvideo",(char *)mux_v); break; case VCODEC_NUV: - sh_video->vfilter=vf_open_encoder(NULL,"nuv",(char *)mux_v); break; + sh_video->vfilter=vf_open_encoder(&opts, NULL,"nuv",(char *)mux_v); break; case VCODEC_X264: - sh_video->vfilter=vf_open_encoder(NULL,"x264",(char *)mux_v); break; + sh_video->vfilter=vf_open_encoder(&opts, NULL,"x264",(char *)mux_v); break; } if(!mux_v->bih || !sh_video->vfilter){ mp_msg(MSGT_MENCODER,MSGL_FATAL,MSGTR_EncoderOpenFailed); @@ -836,9 +838,9 @@ default: { // append 'expand' filter, it fixes stride problems and renders osd: if (auto_expand) { char* vf_args[] = { "osd", "1", NULL }; - sh_video->vfilter=vf_open_filter(sh_video->vfilter,"expand",vf_args); + sh_video->vfilter=vf_open_filter(&opts, sh_video->vfilter,"expand",vf_args); } - sh_video->vfilter=append_filters(sh_video->vfilter); + sh_video->vfilter=append_filters(sh_video->vfilter, opts.vf_settings); mp_msg(MSGT_CPLAYER,MSGL_INFO,"==========================================================================\n"); init_best_video_codec(sh_video,video_codec_list,video_fm_list); @@ -913,7 +915,7 @@ if(mux_a->codec != ACODEC_COPY) { } switch(mux_a->codec){ case ACODEC_COPY: - if (playback_speed != 1.0) mp_msg(MSGT_CPLAYER, MSGL_WARN, MSGTR_NoSpeedWithFrameCopy); + if (opts.playback_speed != 1.0) mp_msg(MSGT_CPLAYER, MSGL_WARN, MSGTR_NoSpeedWithFrameCopy); if (sh_audio->format >= 0x10000) { mp_msg(MSGT_MENCODER,MSGL_ERR,MSGTR_CantCopyAudioFormat, sh_audio->format); mencoder_exit(1,NULL); @@ -941,8 +943,8 @@ case ACODEC_COPY: mux_a->h.dwScale=mux_a->h.dwSampleSize; mux_a->h.dwRate=mux_a->wf->nAvgBytesPerSec; } - mux_a->h.dwRate *= playback_speed; - mux_a->wf->nSamplesPerSec *= playback_speed; + mux_a->h.dwRate *= opts.playback_speed; + mux_a->wf->nSamplesPerSec *= opts.playback_speed; mp_msg(MSGT_MENCODER, MSGL_INFO, MSGTR_ACodecFramecopy, mux_a->wf->wFormatTag, mux_a->wf->nChannels, mux_a->wf->nSamplesPerSec, mux_a->wf->wBitsPerSample, mux_a->wf->nAvgBytesPerSec, mux_a->h.dwSampleSize); @@ -972,17 +974,17 @@ else { mencoder_exit(1,NULL); } if (sh_audio && mux_a->codec == ACODEC_COPY) { - if (playback_speed != 1.0) mp_msg(MSGT_CPLAYER, MSGL_WARN, MSGTR_NoSpeedWithFrameCopy); + if (opts.playback_speed != 1.0) mp_msg(MSGT_CPLAYER, MSGL_WARN, MSGTR_NoSpeedWithFrameCopy); mp_msg(MSGT_MENCODER, MSGL_INFO, MSGTR_ACodecFramecopy, mux_a->wf->wFormatTag, mux_a->wf->nChannels, mux_a->wf->nSamplesPerSec, mux_a->wf->wBitsPerSample, mux_a->wf->nAvgBytesPerSec, mux_a->h.dwSampleSize); if (sh_audio->wf) { if ((mux_a->wf->wFormatTag != sh_audio->wf->wFormatTag) || (mux_a->wf->nChannels != sh_audio->wf->nChannels) || - (mux_a->wf->nSamplesPerSec != sh_audio->wf->nSamplesPerSec * playback_speed)) + (mux_a->wf->nSamplesPerSec != sh_audio->wf->nSamplesPerSec * opts.playback_speed)) { mp_msg(MSGT_MENCODER, MSGL_INFO, MSGTR_ACodecFramecopy, - sh_audio->wf->wFormatTag, sh_audio->wf->nChannels, (int)(sh_audio->wf->nSamplesPerSec * playback_speed), + sh_audio->wf->wFormatTag, sh_audio->wf->nChannels, (int)(sh_audio->wf->nSamplesPerSec * opts.playback_speed), sh_audio->wf->wBitsPerSample, sh_audio->wf->nAvgBytesPerSec, 0); mp_msg(MSGT_MENCODER,MSGL_FATAL,MSGTR_AudioCopyFileMismatch); mencoder_exit(1,NULL); @@ -990,10 +992,10 @@ else { } else { if ((mux_a->wf->wFormatTag != sh_audio->format) || (mux_a->wf->nChannels != sh_audio->channels) || - (mux_a->wf->nSamplesPerSec != sh_audio->samplerate * playback_speed)) + (mux_a->wf->nSamplesPerSec != sh_audio->samplerate * opts.playback_speed)) { mp_msg(MSGT_MENCODER, MSGL_INFO, MSGTR_ACodecFramecopy, - sh_audio->wf->wFormatTag, sh_audio->wf->nChannels, (int)(sh_audio->wf->nSamplesPerSec * playback_speed), + sh_audio->wf->wFormatTag, sh_audio->wf->nChannels, (int)(sh_audio->wf->nSamplesPerSec * opts.playback_speed), sh_audio->wf->wBitsPerSample, sh_audio->wf->nAvgBytesPerSec, 0); mp_msg(MSGT_MENCODER,MSGL_FATAL,MSGTR_AudioCopyFileMismatch); mencoder_exit(1,NULL); @@ -1220,7 +1222,7 @@ if(sh_audio){ frame_data.in_size=video_read_frame(sh_video,&frame_data.frame_time,&frame_data.start,force_fps); sh_video->timer+=frame_data.frame_time; } - frame_data.frame_time /= playback_speed; + frame_data.frame_time /= opts.playback_speed; if(frame_data.in_size<0){ at_eof=1; break; } ++decoded_frameno; @@ -1293,9 +1295,16 @@ case VCODEC_FRAMENO: break; default: // decode_video will callback down to ve_*.c encoders, through the video filters + sh_video->vfilter->control(sh_video->vfilter, VFCTRL_SET_OSD_OBJ, osd); {void *decoded_frame = decode_video(sh_video,frame_data.start,frame_data.in_size, - skip_flag>0 && (!sh_video->vfilter || ((vf_instance_t *)sh_video->vfilter)->control(sh_video->vfilter, VFCTRL_SKIP_NEXT_FRAME, 0) != CONTROL_TRUE), MP_NOPTS_VALUE); - blit_frame = decoded_frame && filter_video(sh_video, decoded_frame, MP_NOPTS_VALUE);} + skip_flag>0 && (!sh_video->vfilter || sh_video->vfilter->control(sh_video->vfilter, VFCTRL_SKIP_NEXT_FRAME, 0) != CONTROL_TRUE), MP_NOPTS_VALUE); + blit_frame = decoded_frame && filter_video(sh_video, decoded_frame, MP_NOPTS_VALUE); + if (blit_frame) { + struct vf_instance *vf = sh_video->vfilter; + vf->control(vf, VFCTRL_DRAW_EOSD, NULL); + vf->control(vf, VFCTRL_DRAW_OSD, osd); + } + } if (sh_video->vf_initialized < 0) mencoder_exit(1, NULL); @@ -1314,7 +1323,7 @@ default: // Eventually this entire block should probably be removed. if(skip_limit==0){ // skipping not allowed -> write empty frame: - if (!encode_duplicates || !sh_video->vfilter || ((vf_instance_t *)sh_video->vfilter)->control(sh_video->vfilter, VFCTRL_DUPLICATE_FRAME, 0) != CONTROL_TRUE) + if (!encode_duplicates || !sh_video->vfilter || sh_video->vfilter->control(sh_video->vfilter, VFCTRL_DUPLICATE_FRAME, 0) != CONTROL_TRUE) muxer_write_chunk(mux_v,0,0, MP_NOPTS_VALUE, MP_NOPTS_VALUE); } else { // skipping allowed -> skip it and distriubute timer error: @@ -1333,7 +1342,7 @@ if(skip_flag<0){ if(!quiet) mp_msg(MSGT_MENCODER, MSGL_WARN, MSGTR_DuplicateFrames,-skip_flag); while(skip_flag<0){ duplicatedframes++; - if (!encode_duplicates || !sh_video->vfilter || ((vf_instance_t *)sh_video->vfilter)->control(sh_video->vfilter, VFCTRL_DUPLICATE_FRAME, 0) != CONTROL_TRUE) + if (!encode_duplicates || !sh_video->vfilter || sh_video->vfilter->control(sh_video->vfilter, VFCTRL_DUPLICATE_FRAME, 0) != CONTROL_TRUE) muxer_write_chunk(mux_v,0,0, MP_NOPTS_VALUE, MP_NOPTS_VALUE); ++skip_flag; } @@ -1369,7 +1378,7 @@ if(sh_audio && !demuxer2){ // av = compensated (with out buffering delay) A-V diff AV_delay=(a_pts-v_pts); AV_delay-=audio_delay; - AV_delay /= playback_speed; + AV_delay /= opts.playback_speed; AV_delay-=mux_a->timer-(mux_v->timer-(v_timer_corr+v_pts_corr)); // adjust for encoder delays AV_delay -= (float) mux_a->encoder_delay * mux_a->h.dwScale/mux_a->h.dwRate; @@ -1379,9 +1388,9 @@ if(sh_audio && !demuxer2){ if(x<-max_pts_correction) x=-max_pts_correction; else if(x> max_pts_correction) x= max_pts_correction; if(default_max_pts_correction>=0) - max_pts_correction=default_max_pts_correction*playback_speed; + max_pts_correction=default_max_pts_correction*opts.playback_speed; else - max_pts_correction=sh_video->frametime*0.10 *playback_speed; // +-10% of time + max_pts_correction=sh_video->frametime*0.10 *opts.playback_speed; // +-10% of time // sh_video->timer-=x; c_total+=x; v_pts_corr+=x; @@ -1497,10 +1506,10 @@ if (!interrupted && filelist[++curfile].name != 0) { /*TODO emit frmaes delayed by decoder lag*/ if(sh_video && sh_video->vfilter){ mp_msg(MSGT_MENCODER, MSGL_INFO, MSGTR_FlushingVideoFrames); - if (!((vf_instance_t *)sh_video->vfilter)->fmt.have_configured) + if (!sh_video->vfilter->fmt.have_configured) mp_msg(MSGT_MENCODER, MSGL_WARN, MSGTR_FiltersHaveNotBeenConfiguredEmptyFile); else - ((vf_instance_t *)sh_video->vfilter)->control(sh_video->vfilter, + sh_video->vfilter->control(sh_video->vfilter, VFCTRL_FLUSH_FRAMES, 0); } @@ -1655,10 +1664,16 @@ static int slowseek(float end_pts, demux_stream_t *d_video, demux_stream_t *d_au if (sh_video->pts >= end_pts) done = 1; if (vfilter) { + sh_video->vfilter->control(sh_video->vfilter, VFCTRL_SET_OSD_OBJ, + osd); int softskip = (vfilter->control(vfilter, VFCTRL_SKIP_NEXT_FRAME, 0) == CONTROL_TRUE); void *decoded_frame = decode_video(sh_video, frame_data->start, frame_data->in_size, !softskip, MP_NOPTS_VALUE); if (decoded_frame) - filter_video(sh_video, decoded_frame, MP_NOPTS_VALUE); + if (filter_video(sh_video, decoded_frame, MP_NOPTS_VALUE)) { + struct vf_instance *vf = sh_video->vfilter; + vf->control(vf, VFCTRL_DRAW_EOSD, NULL); + vf->control(vf, VFCTRL_DRAW_OSD, osd); + } } if (print_info) mp_msg(MSGT_MENCODER, MSGL_STATUS, diff --git a/metadata.h b/metadata.h index 6a31d75f4b..87ed3e8fd9 100644 --- a/metadata.h +++ b/metadata.h @@ -48,7 +48,9 @@ enum metadata_s { META_INFO_GENRE }; -char *get_metadata (metadata_t type); +struct MPContext; + +char *get_metadata(struct MPContext *mpctx, metadata_t type); #endif /* MPLAYER_METADATA_H */ @@ -1,14 +1,10 @@ #ifndef MPLAYER_MP_CORE_H #define MPLAYER_MP_CORE_H -#include "mp_osd.h" -#include "libao2/audio_out.h" -#include "playtree.h" -#include "stream/stream.h" -#include "libmpdemux/demuxer.h" -#include "libmpdemux/stheader.h" +#include <stdbool.h> + +#include "options.h" #include "mixer.h" -#include "libvo/video_out.h" #include "subreader.h" // definitions used internally by the core player code @@ -19,7 +15,6 @@ #define INITIALIZED_GETCH2 8 #define INITIALIZED_SPUDEC 32 #define INITIALIZED_STREAM 64 -#define INITIALIZED_INPUT 128 #define INITIALIZED_VOBSUB 256 #define INITIALIZED_DEMUXER 512 #define INITIALIZED_ACODEC 1024 @@ -33,13 +28,17 @@ #define SUB_SOURCES 3 -#define PT_NEXT_ENTRY 1 -#define PT_PREV_ENTRY -1 -#define PT_NEXT_SRC 2 -#define PT_PREV_SRC -2 -#define PT_UP_NEXT 3 -#define PT_UP_PREV -3 -#define PT_STOP 4 +enum stop_play_reason { + KEEP_PLAYING = 0, // must be 0, numeric values of others do not matter + AT_END_OF_FILE, + PT_NEXT_ENTRY, + PT_PREV_ENTRY, + PT_NEXT_SRC, + PT_PREV_SRC, + PT_UP_NEXT, + PT_UP_PREV, + PT_STOP, +}; typedef enum { EXIT_NONE, @@ -49,35 +48,67 @@ typedef enum { } exit_reason_t; typedef struct MPContext { + struct MPOpts opts; + struct m_config *mconfig; + struct vo_x11_state *x11_state; + struct mp_fifo *key_fifo; + struct input_ctx *input; + struct osd_state *osd; int osd_show_percentage; int osd_function; const ao_functions_t *audio_out; - play_tree_t *playtree; - play_tree_iter_t *playtree_iter; - int eof; + struct play_tree *playtree; + struct play_tree_iter *playtree_iter; + char *filename; // currently playing file + enum stop_play_reason stop_play; int play_tree_step; - int loop_times; - - stream_t *stream; - demuxer_t *demuxer; - sh_audio_t *sh_audio; - sh_video_t *sh_video; - demux_stream_t *d_audio; - demux_stream_t *d_video; - demux_stream_t *d_sub; + unsigned int initialized_flags; // which subsystems have been initialized + + struct stream *stream; + struct demuxer *demuxer; + struct sh_audio *sh_audio; + struct sh_video *sh_video; + struct demux_stream *d_audio; + struct demux_stream *d_video; + struct demux_stream *d_sub; mixer_t mixer; - const vo_functions_t *video_out; + struct vo *video_out; // Frames buffered in the vo ready to flip. Currently always 0 or 1. // This is really a vo variable but currently there's no suitable vo // struct. int num_buffered_frames; + // Show a video frame as quickly as possible without trying to adjust + // for AV sync. Used when starting a file or after seeking. + bool update_video_immediately; // AV sync: the next frame should be shown when the audio out has this // much (in seconds) buffered data left. Increased when more data is // written to the ao, decreased when moving to the next frame. // In the audio-only case used as a timer since the last seek // by the audio CPU usage meter. double delay; + // AV sync: time until next frame should be shown + float time_frame; + // How long the last vo flip() call took. Used to adjust timing with + // the goal of making flip() calls finish (rather than start) at the + // specified time. + float last_vo_flip_duration; + // How much video timing has been changed to make it match the audio + // timeline. Used for status line information only. + double total_avsync_change; + // A-V sync difference when last frame was displayed. Kept to display + // the same value if the status line is updated at a time where no new + // video frame is shown. + double last_av_difference; + + // Timestamp from the last time some timing functions read the + // current time, in (occasionally wrapping) microseconds. Used + // to turn a new time value to a delta from last time. + unsigned int last_time; + + // Used to communicate the parameters of a seek between parts + float rel_seek_secs; + int abs_seek_pos; float begin_skip; ///< start time of the current skip while on edlout mode // audio is muted if either EDL or user activates mute @@ -89,24 +120,26 @@ typedef struct MPContext { int set_of_sub_pos; int set_of_sub_size; int global_sub_indices[SUB_SOURCES]; -#ifdef CONFIG_ASS // set_of_ass_tracks[i] contains subtitles from set_of_subtitles[i] // parsed by libass or NULL if format unsupported - ass_track_t* set_of_ass_tracks[MAX_SUBTITLE_FILES]; -#endif + struct ass_track_s *set_of_ass_tracks[MAX_SUBTITLE_FILES]; sub_data* set_of_subtitles[MAX_SUBTITLE_FILES]; int file_format; -#ifdef CONFIG_DVBIN int last_dvb_step; int dvbin_reopen; -#endif - int was_paused; + int paused; + // step this many frames, then pause + int step_frames; + + // Set after showing warning about decoding being too slow for realtime + // playback rate. Used to avoid showing it multiple times. + bool drop_message_shown; #ifdef CONFIG_DVDNAV - struct mp_image_s *nav_smpi; ///< last decoded dvdnav video image + struct mp_image *nav_smpi; ///< last decoded dvdnav video image unsigned char *nav_buffer; ///< last read dvdnav video frame unsigned char *nav_start; ///< pointer to last read video buffer int nav_in_size; ///< last read size @@ -115,24 +148,22 @@ typedef struct MPContext { // Most of these should not be globals -extern int abs_seek_pos; -extern float rel_seek_secs; extern FILE *edl_fd; extern int file_filter; // These appear in options list -extern float playback_speed; -extern int fixed_vo; extern int forced_subs_only; - -int build_afilter_chain(sh_audio_t *sh_audio, ao_data_t *ao_data); -void uninit_player(unsigned int mask); -void reinit_audio_chain(void); -void init_vo_spudec(void); -double playing_audio_pts(sh_audio_t *sh_audio, demux_stream_t *d_audio, - const ao_functions_t *audio_out); -void exit_player_with_rc(exit_reason_t how, int rc); -void add_subtitles(char *filename, float fps, int noerr); -int reinit_video_chain(void); +struct ao_data; +int build_afilter_chain(struct MPContext *mpctx, struct sh_audio *sh_audio, struct ao_data *ao_data); +void uninit_player(struct MPContext *mpctx, unsigned int mask); +void reinit_audio_chain(struct MPContext *mpctx); +void init_vo_spudec(struct MPContext *mpctx); +double playing_audio_pts(struct MPContext *mpctx); +void exit_player_with_rc(struct MPContext *mpctx, exit_reason_t how, int rc); +void add_subtitles(struct MPContext *mpctx, char *filename, float fps, int noerr); +int reinit_video_chain(struct MPContext *mpctx); +void pause_player(struct MPContext *mpctx); +void unpause_player(struct MPContext *mpctx); +void add_step_frame(struct MPContext *mpctx); #endif /* MPLAYER_MP_CORE_H */ @@ -2,69 +2,82 @@ #include "osdep/timer.h" #include "input/input.h" #include "input/mouse.h" +#include "mp_fifo.h" +#include "talloc.h" +#include "options.h" -int key_fifo_size = 7; -static int *key_fifo_data = NULL; -static int key_fifo_read=0; -static int key_fifo_write=0; +struct mp_fifo { + struct MPOpts *opts; + int *data; + int readpos; + int writepos; + int size; + unsigned last_key_time[2]; + int last_key[2]; +}; -static void mplayer_put_key_internal(int code){ - int fifo_free = key_fifo_read - key_fifo_write - 1; - if (fifo_free < 0) fifo_free += key_fifo_size; -// printf("mplayer_put_key(%d)\n",code); - if (key_fifo_data == NULL) - key_fifo_data = malloc(key_fifo_size * sizeof(int)); - if(!fifo_free) return; // FIFO FULL!! - // reserve some space for key release events to avoid stuck keys - if((code & MP_KEY_DOWN) && fifo_free < (key_fifo_size >> 1)) - return; - key_fifo_data[key_fifo_write]=code; - key_fifo_write=(key_fifo_write+1)%key_fifo_size; +struct mp_fifo *mp_fifo_create(struct MPOpts *opts) +{ + struct mp_fifo *fifo = talloc_zero(NULL, struct mp_fifo); + fifo->opts = opts; + fifo->size = opts->key_fifo_size; + fifo->data = talloc_array_ptrtype(fifo, fifo->data, fifo->size); + return fifo; } -int mplayer_get_key(int fd){ - int key; -// printf("mplayer_get_key(%d)\n",fd); - if (key_fifo_data == NULL) - return MP_INPUT_NOTHING; - if(key_fifo_write==key_fifo_read) return MP_INPUT_NOTHING; - key=key_fifo_data[key_fifo_read]; - key_fifo_read=(key_fifo_read+1)%key_fifo_size; -// printf("mplayer_get_key => %d\n",key); - return key; +static void mplayer_put_key_internal(struct mp_fifo *fifo, int code) +{ + int fifo_free = fifo->readpos - fifo->writepos - 1; + if (fifo_free < 0) + fifo_free += fifo->size; + if (!fifo_free) + return; // FIFO FULL!! + // reserve some space for key release events to avoid stuck keys + if((code & MP_KEY_DOWN) && fifo_free < (fifo->size >> 1)) + return; + fifo->data[fifo->writepos++] = code; + fifo->writepos %= fifo->size; } +int mplayer_get_key(void *ctx, int fd) +{ + struct mp_fifo *fifo = ctx; + if (fifo->writepos == fifo->readpos) + return MP_INPUT_NOTHING; + int key = fifo->data[fifo->readpos++]; + fifo->readpos %= fifo->size; + return key; +} -unsigned doubleclick_time = 300; - -static void put_double(int code) { +static void put_double(struct mp_fifo *fifo, int code) +{ if (code >= MOUSE_BTN0 && code <= MOUSE_BTN9) - mplayer_put_key_internal(code - MOUSE_BTN0 + MOUSE_BTN0_DBL); + mplayer_put_key_internal(fifo, code - MOUSE_BTN0 + MOUSE_BTN0_DBL); } -void mplayer_put_key(int code) { - static unsigned last_key_time[2]; - static int last_key[2]; - unsigned now = GetTimerMS(); - // ignore system-doubleclick if we generate these events ourselves - if (doubleclick_time && - (code & ~MP_KEY_DOWN) >= MOUSE_BTN0_DBL && - (code & ~MP_KEY_DOWN) <= MOUSE_BTN9_DBL) - return; - mplayer_put_key_internal(code); - if (code & MP_KEY_DOWN) { - code &= ~MP_KEY_DOWN; - last_key[1] = last_key[0]; - last_key[0] = code; - last_key_time[1] = last_key_time[0]; - last_key_time[0] = now; - if (last_key[1] == code && - now - last_key_time[1] < doubleclick_time) - put_double(code); - return; - } - if (last_key[0] == code && last_key[1] == code && - now - last_key_time[1] < doubleclick_time) - put_double(code); +void mplayer_put_key(struct mp_fifo *fifo, int code) +{ + unsigned now = GetTimerMS(); + int doubleclick_time = fifo->opts->doubleclick_time; + // ignore system-doubleclick if we generate these events ourselves + if (doubleclick_time + && (code & ~MP_KEY_DOWN) >= MOUSE_BTN0_DBL + && (code & ~MP_KEY_DOWN) <= MOUSE_BTN9_DBL) + return; + mplayer_put_key_internal(fifo, code); + if (code & MP_KEY_DOWN) { + code &= ~MP_KEY_DOWN; + fifo->last_key[1] = fifo->last_key[0]; + fifo->last_key[0] = code; + fifo->last_key_time[1] = fifo->last_key_time[0]; + fifo->last_key_time[0] = now; + if (fifo->last_key[1] == code + && now - fifo->last_key_time[1] < doubleclick_time) + put_double(fifo, code); + return; + } + if (fifo->last_key[0] == code && fifo->last_key[1] == code + && now - fifo->last_key_time[1] < doubleclick_time) + put_double(fifo, code); } @@ -1,7 +1,16 @@ #ifndef MPLAYER_MP_FIFO_H #define MPLAYER_MP_FIFO_H -int mplayer_get_key(int fd); -void mplayer_put_key(int code); +struct mp_fifo; +int mplayer_get_key(void *ctx, int fd); +void mplayer_put_key(struct mp_fifo *fifo, int code); +// Can be freed with talloc_free() +struct MPOpts; +struct mp_fifo *mp_fifo_create(struct MPOpts *opts); + + +#ifdef IS_OLD_VO +#define mplayer_put_key(key) mplayer_put_key(global_vo->key_fifo, key) +#endif #endif /* MPLAYER_MP_FIFO_H */ @@ -19,7 +19,9 @@ extern int osd_duration; extern int term_osd; -void set_osd_bar(int type,const char* name,double min,double max,double val); +struct MPContext; + +void set_osd_bar(struct MPContext *mpctx, int type,const char* name,double min,double max,double val); void set_osd_msg(int id, int level, int time, const char* fmt, ...); void rm_osd_msg(int id); diff --git a/mpcommon.c b/mpcommon.c index 1165fc45ee..99d70c0ef4 100644 --- a/mpcommon.c +++ b/mpcommon.c @@ -1,4 +1,6 @@ #include <stdlib.h> +#include "mpcommon.h" +#include "options.h" #include "stream/stream.h" #include "libmpdemux/demuxer.h" #include "libmpdemux/stheader.h" @@ -69,6 +71,7 @@ if (HAVE_CMOV) void update_subtitles(sh_video_t *sh_video, demux_stream_t *d_dvdsub, int reset) { + struct MPOpts *opts = sh_video->opts; unsigned char *packet=NULL; int len; char type = d_dvdsub->sh ? ((sh_sub_t *)d_dvdsub->sh)->type : 'v'; @@ -99,8 +102,7 @@ void update_subtitles(sh_video_t *sh_video, demux_stream_t *d_dvdsub, int reset) } // DVD sub: - if (vo_config_count && vo_spudec && - (vobsub_id >= 0 || (dvdsub_id >= 0 && type == 'v'))) { + if (vo_spudec && (vobsub_id >= 0 || (opts->sub_id >= 0 && type == 'v'))) { int timestamp; current_module = "spudec"; spudec_heartbeat(vo_spudec, 90000*sh_video->timer); @@ -144,7 +146,8 @@ void update_subtitles(sh_video_t *sh_video, demux_stream_t *d_dvdsub, int reset) if (spudec_changed(vo_spudec)) vo_osd_changed(OSDTYPE_SPU); - } else if (dvdsub_id >= 0 && (type == 't' || type == 'm' || type == 'a')) { + } else if (opts->sub_id >= 0 + && (type == 't' || type == 'm' || type == 'a')) { double curpts = sh_video->pts + sub_delay; double endpts; vo_sub = &subs; @@ -4,7 +4,9 @@ #include <stdio.h> #include <stdlib.h> +#include <stdbool.h> #include "config.h" +#include "talloc.h" #if defined(__MINGW32__) || defined(__CYGWIN__) #define _UWIN 1 /*disable Non-underscored versions of non-ANSI functions as otherwise int eof would conflict with eof()*/ @@ -43,6 +45,8 @@ #include "m_option.h" #include "m_config.h" +#include "mplayer.h" +#include "access_mpcontext.h" #include "m_property.h" #include "cfg-mplayer-def.h" @@ -51,6 +55,7 @@ #include "subreader.h" +#include "mp_osd.h" #include "libvo/video_out.h" #include "libvo/font_load.h" @@ -78,6 +83,7 @@ #include "input/input.h" +const int under_mencoder = 0; int slave_mode=0; int player_idle_mode=0; int quiet=0; @@ -127,27 +133,15 @@ int import_initial_playtree_into_gui(play_tree_t* my_playtree, m_config_t* confi #include "parser-cfg.h" #include "parser-mpcmd.h" -m_config_t* mconfig; - //**************************************************************************// // Config file //**************************************************************************// static int cfg_inc_verbose(m_option_t *conf){ ++verbose; return 0;} -static int cfg_include(m_option_t *conf, char *filename){ - return m_config_parse_config_file(mconfig, filename); -} - #include "get_path.h" //**************************************************************************// -// XScreensaver -//**************************************************************************// - -void xscreensaver_heartbeat(void); - -//**************************************************************************// //**************************************************************************// // Input media streaming & demultiplexer: //**************************************************************************// @@ -175,6 +169,8 @@ static int max_framesize=0; #include "mixer.h" #include "mp_core.h" +#include "options.h" +#include "defaultopts.h" //**************************************************************************// //**************************************************************************// @@ -184,24 +180,6 @@ static int max_framesize=0; int noconsolecontrols=0; //**************************************************************************// -// Not all functions in mplayer.c take the context as an argument yet -static MPContext mpctx_s = { - .osd_function = OSD_PLAY, - .begin_skip = MP_NOPTS_VALUE, - .play_tree_step = 1, - .global_sub_pos = -1, - .set_of_sub_pos = -1, - .file_format = DEMUXER_TYPE_UNKNOWN, - .loop_times = -1, -#ifdef CONFIG_DVBIN - .last_dvb_step = 1, -#endif -}; - -static MPContext *mpctx = &mpctx_s; - -int fixed_vo=0; - // benchmark: double video_time_usage=0; double vout_time_usage=0; @@ -215,8 +193,6 @@ int benchmark=0; int auto_quality=0; static int output_quality=0; -float playback_speed=1.0; - int use_gui=0; #ifdef CONFIG_GUI @@ -244,10 +220,6 @@ static m_time_size_t end_at = { .type = END_AT_NONE, .pos = 0 }; // A/V sync: int autosync=0; // 30 might be a good default value. -// may be changed by GUI: (FIXME!) -float rel_seek_secs=0; -int abs_seek_pos=0; - // codecs: char **audio_codec_list=NULL; // override audio codec char **video_codec_list=NULL; // override video codec @@ -259,15 +231,10 @@ extern char *demuxer_name; // override demuxer extern char *audio_demuxer_name; // override audio demuxer extern char *sub_demuxer_name; // override sub demuxer -// streaming: -int audio_id=-1; -int video_id=-1; -int dvdsub_id=-2; int vobsub_id=-1; char* audio_lang=NULL; char* dvdsub_lang=NULL; static char* spudec_ifo=NULL; -char* filename=NULL; //"MI2-Trailer.avi"; int forced_subs_only=0; int file_filter=1; @@ -288,8 +255,6 @@ static char *stream_dump_name="stream.dump"; // A-V sync: static float default_max_pts_correction=-1;//0.01f; -static float max_pts_correction=0;//default_max_pts_correction; -static float c_total=0; float audio_delay=0; static int ignore_start=0; @@ -302,10 +267,6 @@ static int audio_output_format=-1; // AF_FORMAT_UNKNOWN static int play_n_frames=-1; static int play_n_frames_mf=-1; -// screen info: -char** video_driver_list=NULL; -char** audio_driver_list=NULL; - // sub: char *font_name=NULL; char *sub_font_name=NULL; @@ -333,9 +294,9 @@ char* current_module=NULL; // for debugging #ifdef CONFIG_MENU #include "m_struct.h" #include "libmenu/menu.h" -void vf_menu_pause_update(struct vf_instance_s* vf); +void vf_menu_pause_update(struct vf_instance* vf); extern vf_info_t vf_info_menu; -static vf_info_t* libmenu_vfs[] = { +static const vf_info_t* const libmenu_vfs[] = { &vf_info_menu, NULL }; @@ -357,7 +318,6 @@ short edl_decision = 0; ///< 1 when an EDL operation has been made. FILE* edl_fd = NULL; ///< fd to write to when in -edlout mode. int use_filedir_conf; -static unsigned int initialized_flags=0; #include "mpcommon.h" #include "command.h" @@ -400,7 +360,15 @@ int mpctx_get_osd_function(MPContext *mpctx) return mpctx->osd_function; } -static int is_valid_metadata_type (metadata_t type) { +static float get_relative_time(struct MPContext *mpctx) +{ + unsigned int new_time = GetTimer(); + unsigned int delta = new_time - mpctx->last_time; + mpctx->last_time = new_time; + return delta * 0.000001; +} + +static int is_valid_metadata_type(struct MPContext *mpctx, metadata_t type) { switch (type) { /* check for valid video stream */ @@ -444,7 +412,7 @@ static int is_valid_metadata_type (metadata_t type) { return 1; } -static char *get_demuxer_info (char *tag) { +static char *get_demuxer_info(struct MPContext *mpctx, char *tag) { char **info = mpctx->demuxer->info; int n; @@ -458,19 +426,20 @@ static char *get_demuxer_info (char *tag) { return info[2*n+1] ? strdup (info[2*n+1]) : NULL; } -char *get_metadata (metadata_t type) { +char *get_metadata(struct MPContext *mpctx, metadata_t type) +{ char *meta = NULL; sh_audio_t * const sh_audio = mpctx->sh_audio; sh_video_t * const sh_video = mpctx->sh_video; - if (!is_valid_metadata_type (type)) + if (!is_valid_metadata_type(mpctx, type)) return NULL; switch (type) { case META_NAME: { - return strdup (mp_basename2 (filename)); + return strdup (mp_basename2 (mpctx->filename)); } case META_VIDEO_CODEC: @@ -533,25 +502,25 @@ char *get_metadata (metadata_t type) { /* check for valid demuxer */ case META_INFO_TITLE: - return get_demuxer_info ("Title"); + return get_demuxer_info(mpctx, "Title"); case META_INFO_ARTIST: - return get_demuxer_info ("Artist"); + return get_demuxer_info(mpctx, "Artist"); case META_INFO_ALBUM: - return get_demuxer_info ("Album"); + return get_demuxer_info(mpctx, "Album"); case META_INFO_YEAR: - return get_demuxer_info ("Year"); + return get_demuxer_info(mpctx, "Year"); case META_INFO_COMMENT: - return get_demuxer_info ("Comment"); + return get_demuxer_info(mpctx, "Comment"); case META_INFO_TRACK: - return get_demuxer_info ("Track"); + return get_demuxer_info(mpctx, "Track"); case META_INFO_GENRE: - return get_demuxer_info ("Genre"); + return get_demuxer_info(mpctx, "Genre"); default: break; @@ -574,13 +543,13 @@ static void mp_dvdnav_context_free(MPContext *ctx){ } #endif -void uninit_player(unsigned int mask){ - mask=initialized_flags&mask; +void uninit_player(struct MPContext *mpctx, unsigned int mask){ + mask=mpctx->initialized_flags&mask; mp_msg(MSGT_CPLAYER,MSGL_DBG2,"\n*** uninit(0x%X)\n",mask); if(mask&INITIALIZED_ACODEC){ - initialized_flags&=~INITIALIZED_ACODEC; + mpctx->initialized_flags&=~INITIALIZED_ACODEC; current_module="uninit_acodec"; if(mpctx->sh_audio) uninit_audio(mpctx->sh_audio); #ifdef CONFIG_GUI @@ -591,7 +560,7 @@ void uninit_player(unsigned int mask){ } if(mask&INITIALIZED_VCODEC){ - initialized_flags&=~INITIALIZED_VCODEC; + mpctx->initialized_flags&=~INITIALIZED_VCODEC; current_module="uninit_vcodec"; if(mpctx->sh_video) uninit_video(mpctx->sh_video); mpctx->sh_video=NULL; @@ -601,7 +570,7 @@ void uninit_player(unsigned int mask){ } if(mask&INITIALIZED_DEMUXER){ - initialized_flags&=~INITIALIZED_DEMUXER; + mpctx->initialized_flags&=~INITIALIZED_DEMUXER; current_module="free_demuxer"; if(mpctx->demuxer){ mpctx->stream=mpctx->demuxer->stream; @@ -612,16 +581,16 @@ void uninit_player(unsigned int mask){ // kill the cache process: if(mask&INITIALIZED_STREAM){ - initialized_flags&=~INITIALIZED_STREAM; + mpctx->initialized_flags&=~INITIALIZED_STREAM; current_module="uninit_stream"; if(mpctx->stream) free_stream(mpctx->stream); mpctx->stream=NULL; } if(mask&INITIALIZED_VO){ - initialized_flags&=~INITIALIZED_VO; + mpctx->initialized_flags&=~INITIALIZED_VO; current_module="uninit_vo"; - mpctx->video_out->uninit(); + vo_destroy(mpctx->video_out); mpctx->video_out=NULL; #ifdef CONFIG_DVDNAV mp_dvdnav_context_free(mpctx); @@ -630,7 +599,7 @@ void uninit_player(unsigned int mask){ // Must be after libvo uninit, as few vo drivers (svgalib) have tty code. if(mask&INITIALIZED_GETCH2){ - initialized_flags&=~INITIALIZED_GETCH2; + mpctx->initialized_flags&=~INITIALIZED_GETCH2; current_module="uninit_getch2"; mp_msg(MSGT_CPLAYER,MSGL_DBG2,"\n[[[uninit getch2]]]\n"); // restore terminal: @@ -638,51 +607,42 @@ void uninit_player(unsigned int mask){ } if(mask&INITIALIZED_VOBSUB){ - initialized_flags&=~INITIALIZED_VOBSUB; + mpctx->initialized_flags&=~INITIALIZED_VOBSUB; current_module="uninit_vobsub"; if(vo_vobsub) vobsub_close(vo_vobsub); vo_vobsub=NULL; } if (mask&INITIALIZED_SPUDEC){ - initialized_flags&=~INITIALIZED_SPUDEC; + mpctx->initialized_flags&=~INITIALIZED_SPUDEC; current_module="uninit_spudec"; spudec_free(vo_spudec); vo_spudec=NULL; } if(mask&INITIALIZED_AO){ - initialized_flags&=~INITIALIZED_AO; + mpctx->initialized_flags&=~INITIALIZED_AO; current_module="uninit_ao"; if (mpctx->edl_muted) mixer_mute(&mpctx->mixer); - mpctx->audio_out->uninit(mpctx->eof?0:1); mpctx->audio_out=NULL; + mpctx->audio_out->uninit(mpctx->stop_play != AT_END_OF_FILE); + mpctx->audio_out=NULL; } #ifdef CONFIG_GUI if(mask&INITIALIZED_GUI){ - initialized_flags&=~INITIALIZED_GUI; + mpctx->initialized_flags&=~INITIALIZED_GUI; current_module="uninit_gui"; guiDone(); } #endif - if(mask&INITIALIZED_INPUT){ - initialized_flags&=~INITIALIZED_INPUT; - current_module="uninit_input"; - mp_input_uninit(); -#ifdef CONFIG_MENU - if (use_menu) - menu_uninit(); -#endif - } - current_module=NULL; } -void exit_player_with_rc(exit_reason_t how, int rc){ - +void exit_player_with_rc(struct MPContext *mpctx, exit_reason_t how, int rc) +{ if (mpctx->user_muted && !mpctx->edl_muted) mixer_mute(&mpctx->mixer); - uninit_player(INITIALIZED_ALL); + uninit_player(mpctx, INITIALIZED_ALL); #if defined(__MINGW32__) || defined(__CYGWIN__) timeEndPeriod(1); #endif @@ -690,18 +650,25 @@ void exit_player_with_rc(exit_reason_t how, int rc){ #ifdef CONFIG_GUI if ( !use_gui ) #endif - vo_uninit(); // Close the X11 connection (if any is open). + vo_uninit(mpctx->x11_state); // Close the X11 connection (if any is open). +#endif + + current_module="uninit_input"; + mp_input_uninit(mpctx->input); +#ifdef CONFIG_MENU + if (use_menu) + menu_uninit(); #endif #ifdef CONFIG_FREETYPE current_module="uninit_font"; - if (sub_font && sub_font != vo_font) free_font_desc(sub_font); - sub_font = NULL; - if (vo_font) free_font_desc(vo_font); + if (mpctx->osd && mpctx->osd->sub_font != vo_font) + free_font_desc(mpctx->osd->sub_font); + free_font_desc(vo_font); vo_font = NULL; done_freetype(); #endif - free_osd_list(); + osd_free(mpctx->osd); #ifdef CONFIG_ASS ass_library_done(ass_library); @@ -710,12 +677,13 @@ void exit_player_with_rc(exit_reason_t how, int rc){ current_module="exit_player"; // free mplayer config - if(mconfig) - m_config_free(mconfig); + if(mpctx->mconfig) + m_config_free(mpctx->mconfig); if(mpctx->playtree) play_tree_free(mpctx->playtree, 1); + talloc_free(mpctx->key_fifo); if(edl_records != NULL) free(edl_records); // free mem allocated for EDL switch(how) { @@ -739,8 +707,9 @@ void exit_player_with_rc(exit_reason_t how, int rc){ exit(rc); } -void exit_player(exit_reason_t how){ - exit_player_with_rc(how, 1); +static void exit_player(struct MPContext *mpctx, exit_reason_t how) +{ + exit_player_with_rc(mpctx, how, 1); } #ifndef __MINGW32__ @@ -761,7 +730,6 @@ static void exit_sighandler(int x){ if (!crash_debug || x != SIGTRAP) #endif ++sig_count; - if(initialized_flags==0 && sig_count>1) exit(1); if(sig_count==5) { /* We're crashing bad and can't uninit cleanly :( @@ -826,17 +794,20 @@ static void exit_sighandler(int x){ exit(1); } -void mp_input_register_options(m_config_t* cfg); - #include "cfg-mplayer.h" -static void parse_cfgfiles( m_config_t* conf ) +static int cfg_include(m_option_t *conf, char *filename) +{ + return m_config_parse_config_file(conf->priv, filename); +} + +static void parse_cfgfiles(struct MPContext *mpctx, m_config_t* conf) { char *conffile; int conffile_fd; if (!disable_system_conf && m_config_parse_config_file(conf, MPLAYER_CONFDIR "/mplayer.conf") < 0) - exit_player(EXIT_NONE); + exit_player(mpctx, EXIT_NONE); if ((conffile = get_path("")) == NULL) { mp_msg(MSGT_CPLAYER,MSGL_WARN,MSGTR_NoHomeDir); } else { @@ -856,7 +827,7 @@ if ((conffile = get_path("")) == NULL) { } if (!disable_user_conf && m_config_parse_config_file(conf, conffile) < 0) - exit_player(EXIT_NONE); + exit_player(mpctx, EXIT_NONE); free(conffile); } } @@ -894,7 +865,7 @@ static void load_per_extension_config (m_config_t* conf, const char *const file) m_profile_t *p; /* does filename actually have an extension ? */ - str = strrchr (filename, '.'); + str = strrchr (file, '.'); if (!str) return; @@ -962,38 +933,39 @@ static void load_per_file_config (m_config_t* conf, const char *const file) * cache filling) if the operation fails we use this function to check * if it was interrupted by the user. * The function returns a new value for eof. */ -static int libmpdemux_was_interrupted(int eof) { +static int libmpdemux_was_interrupted(struct MPContext *mpctx, int stop_play) +{ mp_cmd_t* cmd; - if((cmd = mp_input_get_cmd(0,0,0)) != NULL) { + if((cmd = mp_input_get_cmd(mpctx->input, 0,0,0)) != NULL) { switch(cmd->id) { case MP_CMD_QUIT: - exit_player_with_rc(EXIT_QUIT, (cmd->nargs > 0)? cmd->args[0].v.i : 0); + exit_player_with_rc(mpctx, EXIT_QUIT, (cmd->nargs > 0)? cmd->args[0].v.i : 0); case MP_CMD_PLAY_TREE_STEP: { - eof = (cmd->args[0].v.i > 0) ? PT_NEXT_ENTRY : PT_PREV_ENTRY; + stop_play = (cmd->args[0].v.i > 0) ? PT_NEXT_ENTRY : PT_PREV_ENTRY; mpctx->play_tree_step = (cmd->args[0].v.i == 0) ? 1 : cmd->args[0].v.i; } break; case MP_CMD_PLAY_TREE_UP_STEP: { - eof = (cmd->args[0].v.i > 0) ? PT_UP_NEXT : PT_UP_PREV; + stop_play = (cmd->args[0].v.i > 0) ? PT_UP_NEXT : PT_UP_PREV; } break; case MP_CMD_PLAY_ALT_SRC_STEP: { - eof = (cmd->args[0].v.i > 0) ? PT_NEXT_SRC : PT_PREV_SRC; + stop_play = (cmd->args[0].v.i > 0) ? PT_NEXT_SRC : PT_PREV_SRC; } break; } mp_cmd_free(cmd); } - return eof; + return stop_play; } #define mp_basename(s) (strrchr(s,'\\')==NULL?(mp_basename2(s)):(strrchr(s,'\\')+1)) -static int playtree_add_playlist(play_tree_t* entry) +static int playtree_add_playlist(struct MPContext *mpctx, play_tree_t* entry) { - play_tree_add_bpf(entry,filename); + play_tree_add_bpf(entry,mpctx->filename); #ifdef CONFIG_GUI if (use_gui) { if (entry) { - import_playtree_playlist_into_gui(entry, mconfig); + import_playtree_playlist_into_gui(entry, mpctx->mconfig); play_tree_free_list(entry,1); } } else @@ -1023,7 +995,7 @@ static int playtree_add_playlist(play_tree_t* entry) return PT_NEXT_SRC; } -void add_subtitles(char *filename, float fps, int noerr) +void add_subtitles(struct MPContext *mpctx, char *filename, float fps, int noerr) { sub_data *subd; #ifdef CONFIG_ASS @@ -1068,7 +1040,7 @@ void add_subtitles(char *filename, float fps, int noerr) } // FIXME: if/when the GUI calls this, global sub numbering gets (potentially) broken. -void update_set_of_subtitles(void) +void update_set_of_subtitles(struct MPContext *mpctx) // subdata was changed, set_of_sub... have to be updated. { sub_data ** const set_of_subtitles = mpctx->set_of_subtitles; @@ -1089,10 +1061,11 @@ void update_set_of_subtitles(void) } } -void init_vo_spudec(void) { +void init_vo_spudec(struct MPContext *mpctx) +{ if (vo_spudec) spudec_free(vo_spudec); - initialized_flags &= ~INITIALIZED_SPUDEC; + mpctx->initialized_flags &= ~INITIALIZED_SPUDEC; vo_spudec = NULL; if (spudec_ifo) { unsigned int palette[16], width, height; @@ -1126,7 +1099,7 @@ void init_vo_spudec(void) { } if (vo_spudec!=NULL) - initialized_flags|=INITIALIZED_SPUDEC; + mpctx->initialized_flags|=INITIALIZED_SPUDEC; } /* @@ -1181,15 +1154,25 @@ static void sadd_hhmmssf(char *buf, unsigned *pos, int len, float time) { saddf(buf, pos, len, "%02d.%1d", ss, f1); } -/** - * \brief print the status line - * \param a_pos audio position - * \param a_v A-V desynchronization - * \param corr amount out A-V synchronization - */ -static void print_status(float a_pos, float a_v, float corr) +static void print_status(struct MPContext *mpctx, double a_pos, bool at_frame) { + struct MPOpts *opts = &mpctx->opts; sh_video_t * const sh_video = mpctx->sh_video; + + if (mpctx->sh_audio && a_pos == MP_NOPTS_VALUE) + a_pos = playing_audio_pts(mpctx); + if (mpctx->sh_audio && sh_video && at_frame) { + mpctx->last_av_difference = a_pos - sh_video->pts - audio_delay; + if (mpctx->last_av_difference > 0.5 && drop_frame_cnt > 50 + && !mpctx->drop_message_shown) { + mp_msg(MSGT_AVSYNC,MSGL_WARN,MSGTR_SystemTooSlow); + mpctx->drop_message_shown = true; + } + } + if (quiet) + return; + + int width; char *line; unsigned pos = 0; @@ -1224,7 +1207,8 @@ static void print_status(float a_pos, float a_v, float corr) // A-V sync if (mpctx->sh_audio && sh_video) - saddf(line, &pos, width, "A-V:%7.3f ct:%7.3f ", a_v, corr); + saddf(line, &pos, width, "A-V:%7.3f ct:%7.3f ", + mpctx->last_av_difference, mpctx->total_avsync_change); // Video stats if (sh_video) @@ -1236,9 +1220,9 @@ static void print_status(float a_pos, float a_v, float corr) if (sh_video) { if (sh_video->timer > 0.5) saddf(line, &pos, width, "%2d%% %2d%% %4.1f%% ", - (int)(100.0*video_time_usage*playback_speed/(double)sh_video->timer), - (int)(100.0*vout_time_usage*playback_speed/(double)sh_video->timer), - (100.0*audio_time_usage*playback_speed/(double)sh_video->timer)); + (int)(100.0*video_time_usage*opts->playback_speed/(double)sh_video->timer), + (int)(100.0*vout_time_usage*opts->playback_speed/(double)sh_video->timer), + (100.0*audio_time_usage*opts->playback_speed/(double)sh_video->timer)); else saddf(line, &pos, width, "??%% ??%% ??,?%% "); } else if (mpctx->sh_audio) { @@ -1260,8 +1244,8 @@ static void print_status(float a_pos, float a_v, float corr) #endif // other - if (playback_speed != 1) - saddf(line, &pos, width, "%4.2fx ", playback_speed); + if (opts->playback_speed != 1) + saddf(line, &pos, width, "%4.2fx ", opts->playback_speed); // end if (erase_to_end_of_line) { @@ -1281,8 +1265,9 @@ static void print_status(float a_pos, float a_v, float corr) * \param sh_audio describes the requested input format of the chain. * \param ao_data describes the requested output format of the chain. */ -int build_afilter_chain(sh_audio_t *sh_audio, ao_data_t *ao_data) +int build_afilter_chain(struct MPContext *mpctx, sh_audio_t *sh_audio, ao_data_t *ao_data) { + struct MPOpts *opts = &mpctx->opts; int new_srate; int result; if (!sh_audio) @@ -1295,17 +1280,17 @@ int build_afilter_chain(sh_audio_t *sh_audio, ao_data_t *ao_data) } if(af_control_any_rev(sh_audio->afilter, AF_CONTROL_PLAYBACK_SPEED | AF_CONTROL_SET, - &playback_speed)) { + &opts->playback_speed)) { new_srate = sh_audio->samplerate; } else { - new_srate = sh_audio->samplerate * playback_speed; + new_srate = sh_audio->samplerate * opts->playback_speed; if (new_srate != ao_data->samplerate) { // limits are taken from libaf/af_resample.c if (new_srate < 8000) new_srate = 8000; if (new_srate > 192000) new_srate = 192000; - playback_speed = (float)new_srate / (float)sh_audio->samplerate; + opts->playback_speed = (float)new_srate / (float)sh_audio->samplerate; } } result = init_audio_filters(sh_audio, new_srate, @@ -1416,7 +1401,8 @@ static void clear_osd_msgs(void) { * */ -static mp_osd_msg_t* get_osd_msg(void) { +static mp_osd_msg_t* get_osd_msg(struct MPContext *mpctx) +{ mp_osd_msg_t *msg,*prev,*last = NULL; static unsigned last_update = 0; unsigned now = GetTimerMS(); @@ -1430,8 +1416,7 @@ static mp_osd_msg_t* get_osd_msg(void) { osd_visible = 0; vo_osd_progbar_type = -1; // disable vo_osd_changed(OSDTYPE_PROGBAR); - if (mpctx->osd_function != OSD_PAUSE) - mpctx->osd_function = OSD_PLAY; + mpctx->osd_function = mpctx->paused ? OSD_PAUSE : OSD_PLAY; } } @@ -1475,7 +1460,7 @@ static mp_osd_msg_t* get_osd_msg(void) { * */ -void set_osd_bar(int type,const char* name,double min,double max,double val) { +void set_osd_bar(struct MPContext *mpctx, int type,const char* name,double min,double max,double val) { if(osd_level < 1) return; @@ -1501,18 +1486,16 @@ void set_osd_bar(int type,const char* name,double min,double max,double val) { * */ -static void update_osd_msg(void) { +static void update_osd_msg(struct MPContext *mpctx) +{ mp_osd_msg_t *msg; - static char osd_text[128] = ""; - static char osd_text_timer[128]; - - // we need some mem for vo_osd_text - vo_osd_text = (unsigned char*)osd_text; + struct osd_state *osd = mpctx->osd; + char osd_text_timer[128]; // Look if we have a msg - if((msg = get_osd_msg())) { - if(strcmp(osd_text,msg->msg)) { - strncpy((char*)osd_text, msg->msg, 127); + if((msg = get_osd_msg(mpctx))) { + if (strcmp(osd->osd_text, msg->msg)) { + strncpy(osd->osd_text, msg->msg, 127); if(mpctx->sh_video) vo_osd_changed(OSDTYPE_OSD); else if(term_osd) mp_msg(MSGT_CPLAYER,MSGL_STATUS,"%s%s\n",term_osd_esc,msg->msg); } @@ -1551,16 +1534,16 @@ static void update_osd_msg(void) { if(mpctx->osd_show_percentage) mpctx->osd_show_percentage--; - if(strcmp(osd_text,osd_text_timer)) { - strncpy(osd_text, osd_text_timer, 63); + if (strcmp(osd->osd_text, osd_text_timer)) { + strncpy(osd->osd_text, osd_text_timer, 63); vo_osd_changed(OSDTYPE_OSD); } return; } // Clear the term osd line - if(term_osd && osd_text[0]) { - osd_text[0] = 0; + if (term_osd && osd->osd_text[0]) { + osd->osd_text[0] = 0; printf("%s\n",term_osd_esc); } } @@ -1569,7 +1552,9 @@ static void update_osd_msg(void) { // OSDMsgStack -void reinit_audio_chain(void) { +void reinit_audio_chain(struct MPContext *mpctx) +{ + struct MPOpts *opts = &mpctx->opts; if(mpctx->sh_audio){ current_module="init_audio_codec"; mp_msg(MSGT_CPLAYER,MSGL_INFO,"==========================================================================\n"); @@ -1578,7 +1563,7 @@ if(mpctx->sh_audio){ mpctx->d_audio->id = -2; return; } else - initialized_flags|=INITIALIZED_ACODEC; + mpctx->initialized_flags|=INITIALIZED_ACODEC; mp_msg(MSGT_CPLAYER,MSGL_INFO,"==========================================================================\n"); @@ -1595,24 +1580,24 @@ if(mpctx->sh_audio){ // output: &ao_data.samplerate, &ao_data.channels, &ao_data.format)){ mp_msg(MSGT_CPLAYER,MSGL_ERR,MSGTR_AudioFilterChainPreinitError); - exit_player(EXIT_ERROR); + exit_player(mpctx, EXIT_ERROR); } #endif current_module="ao2_init"; - if(!(mpctx->audio_out=init_best_audio_out(audio_driver_list, + if(!(mpctx->audio_out=init_best_audio_out(opts->audio_driver_list, 0, // plugin flag ao_data.samplerate, ao_data.channels, ao_data.format,0))){ // FAILED: mp_msg(MSGT_CPLAYER,MSGL_ERR,MSGTR_CannotInitAO); - uninit_player(INITIALIZED_ACODEC); // close codec + uninit_player(mpctx, INITIALIZED_ACODEC); // close codec mpctx->sh_audio=mpctx->d_audio->sh=NULL; // -> nosound mpctx->d_audio->id = -2; return; } else { // SUCCESS: - initialized_flags|=INITIALIZED_AO; + mpctx->initialized_flags|=INITIALIZED_AO; mp_msg(MSGT_CPLAYER,MSGL_INFO,"AO: [%s] %dHz %dch %s (%d bytes per sample)\n", mpctx->audio_out->info->short_name, ao_data.samplerate, ao_data.channels, @@ -1625,10 +1610,10 @@ if(mpctx->sh_audio){ // init audio filters: #if 1 current_module="af_init"; - if(!build_afilter_chain(mpctx->sh_audio, &ao_data)) { + if(!build_afilter_chain(mpctx, mpctx->sh_audio, &ao_data)) { mp_msg(MSGT_CPLAYER,MSGL_ERR,MSGTR_NoMatchingFilter); // mp_msg(MSGT_CPLAYER,MSGL_ERR,"Couldn't find matching filter / ao format! -> NOSOUND\n"); -// uninit_player(INITIALIZED_ACODEC|INITIALIZED_AO); // close codec & ao +// uninit_player(mpctx, INITIALIZED_ACODEC|INITIALIZED_AO); // close codec & ao // sh_audio=mpctx->d_audio->sh=NULL; // -> nosound } #endif @@ -1645,8 +1630,10 @@ if(mpctx->sh_audio){ // Return pts value corresponding to the end point of audio written to the // ao so far. -static double written_audio_pts(sh_audio_t *sh_audio, demux_stream_t *d_audio) +static double written_audio_pts(struct MPContext *mpctx) { + sh_audio_t *sh_audio = mpctx->sh_audio; + demux_stream_t *d_audio = mpctx->d_audio; double buffered_output; // first calculate the end pts of audio that has been output by decoder double a_pts = sh_audio->pts; @@ -1689,31 +1676,31 @@ static double written_audio_pts(sh_audio_t *sh_audio, demux_stream_t *d_audio) // Filters divide audio length by playback_speed, so multiply by it // to get the length in original units without speedup or slowdown - a_pts -= buffered_output * playback_speed / ao_data.bps; + a_pts -= buffered_output * mpctx->opts.playback_speed / ao_data.bps; return a_pts; } // Return pts value corresponding to currently playing audio. -double playing_audio_pts(sh_audio_t *sh_audio, demux_stream_t *d_audio, - const ao_functions_t *audio_out) +double playing_audio_pts(struct MPContext *mpctx) { - return written_audio_pts(sh_audio, d_audio) - playback_speed * - audio_out->get_delay(); + return written_audio_pts(mpctx) - mpctx->opts.playback_speed * + mpctx->audio_out->get_delay(); } -static int check_framedrop(double frame_time) { +static int check_framedrop(struct MPContext *mpctx, double frame_time) { + struct MPOpts *opts = &mpctx->opts; // check for frame-drop: current_module = "check_framedrop"; if (mpctx->sh_audio && !mpctx->d_audio->eof) { static int dropped_frames; - float delay = playback_speed*mpctx->audio_out->get_delay(); + float delay = opts->playback_speed*mpctx->audio_out->get_delay(); float d = delay-mpctx->delay; ++total_frame_cnt; // we should avoid dropping too many frames in sequence unless we // are too late. and we allow 100ms A-V delay here: - if (d < -dropped_frames*frame_time-0.100 && - mpctx->osd_function != OSD_PAUSE) { + if (d < -dropped_frames*frame_time-0.100 && !mpctx->paused + && !mpctx->update_video_immediately) { ++drop_frame_cnt; ++dropped_frames; return frame_dropping; @@ -1723,53 +1710,12 @@ static int check_framedrop(double frame_time) { return 0; } -static int generate_video_frame(sh_video_t *sh_video, demux_stream_t *d_video) -{ - unsigned char *start; - int in_size; - int hit_eof=0; - double pts; - - while (1) { - int drop_frame = check_framedrop(sh_video->frametime); - void *decoded_frame; - current_module = "decode video"; - // XXX Time used in this call is not counted in any performance - // timer now, OSD is not updated correctly for filter-added frames - if (vf_output_queued_frame(sh_video->vfilter)) - break; - current_module = "video_read_frame"; - in_size = ds_get_packet_pts(d_video, &start, &pts); - if (in_size < 0) { - // try to extract last frames in case of decoder lag - in_size = 0; - pts = 1e300; - hit_eof = 1; - } - if (in_size > max_framesize) - max_framesize = in_size; - current_module = "decode video"; - decoded_frame = decode_video(sh_video, start, in_size, drop_frame, pts); - if (decoded_frame) { - update_subtitles(sh_video, mpctx->d_sub, 0); - update_teletext(sh_video, mpctx->demuxer, 0); - update_osd_msg(); - current_module = "filter video"; - if (filter_video(sh_video, decoded_frame, sh_video->pts)) - break; - } else if (drop_frame) - return -1; - if (hit_eof) - return 0; - } - return 1; -} #ifdef HAVE_RTC int rtc_fd = -1; #endif -static float timing_sleep(float time_frame) +static float timing_sleep(struct MPContext *mpctx, float time_frame) { #ifdef HAVE_RTC if (rtc_fd >= 0){ @@ -1779,7 +1725,7 @@ static float timing_sleep(float time_frame) unsigned long rtc_ts; if (read(rtc_fd, &rtc_ts, sizeof(rtc_ts)) <= 0) mp_msg(MSGT_CPLAYER, MSGL_ERR, MSGTR_LinuxRTCReadError, strerror(errno)); - time_frame -= GetRelativeTime(); + time_frame -= get_relative_time(mpctx); } } else #endif @@ -1790,14 +1736,14 @@ static float timing_sleep(float time_frame) current_module = "sleep_timer"; while (time_frame > margin) { usec_sleep(1000000 * (time_frame - margin)); - time_frame -= GetRelativeTime(); + time_frame -= get_relative_time(mpctx); } if (softsleep){ current_module = "sleep_soft"; if (time_frame < 0) mp_msg(MSGT_AVSYNC, MSGL_WARN, MSGTR_SoftsleepUnderflow); while (time_frame > 0) - time_frame-=GetRelativeTime(); // burn the CPU + time_frame -= get_relative_time(mpctx); // burn the CPU } } return time_frame; @@ -1834,6 +1780,7 @@ static mp_image_t * mp_dvdnav_copy_mpi(mp_image_t *to_mpi, } static void mp_dvdnav_reset_stream (MPContext *ctx) { + struct MPOpts *opts = &ctx->opts; if (ctx->sh_video) { /// clear video pts ctx->d_video->pts = 0.0f; @@ -1858,7 +1805,7 @@ static void mp_dvdnav_reset_stream (MPContext *ctx) { resync_audio_stream(ctx->sh_audio); } - if (ctx->d_sub) dvdsub_id = -2; + if (ctx->d_sub) opts->sub_id = -2; audio_delay = 0.0f; @@ -1867,7 +1814,8 @@ static void mp_dvdnav_reset_stream (MPContext *ctx) { } /// Restore last decoded DVDNAV (still frame) -static mp_image_t *mp_dvdnav_restore_smpi(int *in_size, +static mp_image_t *mp_dvdnav_restore_smpi(struct MPContext *mpctx, + int *in_size, unsigned char **start, mp_image_t *decoded_frame) { @@ -1911,7 +1859,7 @@ static mp_image_t *mp_dvdnav_restore_smpi(int *in_size, } /// Save last decoded DVDNAV (still frame) -static void mp_dvdnav_save_smpi(int in_size, +static void mp_dvdnav_save_smpi(struct MPContext *mpctx, int in_size, unsigned char *start, mp_image_t *decoded_frame) { @@ -1932,72 +1880,44 @@ static void mp_dvdnav_save_smpi(int in_size, } #endif /* CONFIG_DVDNAV */ -static void adjust_sync_and_print_status(int between_frames, float timing_error) +/* Modify video timing to match the audio timeline. There are two main + * reasons this is needed. First, video and audio can start from different + * positions at beginning of file or after a seek (MPlayer starts both + * immediately even if they have different pts). Second, the file can have + * audio timestamps that are inconsistent with the duration of the audio + * packets, for example two consecutive timestamp values differing by + * one second but only a packet with enough samples for half a second + * of playback between them. + */ +static void adjust_sync(struct MPContext *mpctx, double frame_time) { - current_module="av_sync"; + struct MPOpts *opts = &mpctx->opts; + current_module = "av_sync"; - if(mpctx->sh_audio){ - double a_pts, v_pts; - - if (autosync) - /* - * If autosync is enabled, the value for delay must be calculated - * a bit differently. It is set only to the difference between - * the audio and video timers. Any attempt to include the real - * or corrected delay causes the pts_correction code below to - * try to correct for the changes in delay which autosync is - * trying to measure. This keeps the two from competing, but still - * allows the code to correct for PTS drift *only*. (Using a delay - * value here, even a "corrected" one, would be incompatible with - * autosync mode.) - */ - a_pts = written_audio_pts(mpctx->sh_audio, mpctx->d_audio) - mpctx->delay; - else - a_pts = playing_audio_pts(mpctx->sh_audio, mpctx->d_audio, mpctx->audio_out); - - v_pts = mpctx->sh_video->pts; - - { - static int drop_message=0; - double AV_delay = a_pts - audio_delay - v_pts; - double x; - if (AV_delay>0.5 && drop_frame_cnt>50 && drop_message==0){ - ++drop_message; - mp_msg(MSGT_AVSYNC,MSGL_WARN,MSGTR_SystemTooSlow); - } - if (autosync) - x = AV_delay*0.1f; - else - /* Do not correct target time for the next frame if this frame - * was late not because of wrong target time but because the - * target time could not be met */ - x = (AV_delay + timing_error * playback_speed) * 0.1f; - if (x < -max_pts_correction) - x = -max_pts_correction; - else if (x> max_pts_correction) - x = max_pts_correction; - if (default_max_pts_correction >= 0) - max_pts_correction = default_max_pts_correction; - else - max_pts_correction = mpctx->sh_video->frametime*0.10; // +-10% of time - if (!between_frames) { - mpctx->delay+=x; - c_total+=x; - } - if(!quiet) - print_status(a_pts - audio_delay, AV_delay, c_total); - } - - } else { - // No audio: - - if (!quiet) - print_status(0, 0, 0); - } -} + if (!mpctx->sh_audio) + return; -static int fill_audio_out_buffers(void) + double a_pts = written_audio_pts(mpctx) - mpctx->delay; + double v_pts = mpctx->sh_video->pts; + double av_delay = a_pts - v_pts; + // Try to sync vo_flip() so it will *finish* at given time + av_delay += mpctx->last_vo_flip_duration; + av_delay -= audio_delay; // This much pts difference is desired + + double change = av_delay * 0.1; + double max_change = default_max_pts_correction >= 0 ? + default_max_pts_correction : frame_time * 0.1; + if (change < -max_change) + change = -max_change; + else if (change > max_change) + change = max_change; + mpctx->delay += change; + mpctx->total_avsync_change += change; +} + +static int fill_audio_out_buffers(struct MPContext *mpctx) { + struct MPOpts *opts = &mpctx->opts; unsigned int t; double tt; int playsize; @@ -2064,7 +1984,7 @@ static int fill_audio_out_buffers(void) sh_audio->a_out_buffer_len -= playsize; memmove(sh_audio->a_out_buffer, &sh_audio->a_out_buffer[playsize], sh_audio->a_out_buffer_len); - mpctx->delay += playback_speed*playsize/(double)ao_data.bps; + mpctx->delay += opts->playback_speed*playsize/(double)ao_data.bps; } else if (audio_eof && mpctx->audio_out->get_delay() < .04) { // Sanity check to avoid hanging in case current ao doesn't output @@ -2076,12 +1996,14 @@ static int fill_audio_out_buffers(void) return 1; } -static int sleep_until_update(float *time_frame, float *aq_sleep_time) +static int sleep_until_update(struct MPContext *mpctx, float *time_frame, + float *aq_sleep_time) { + struct MPOpts *opts = &mpctx->opts; int frame_time_remaining = 0; current_module="calc_sleep_time"; - *time_frame -= GetRelativeTime(); // reset timer + *time_frame -= get_relative_time(mpctx); // reset timer if (mpctx->sh_audio && !mpctx->d_audio->eof) { float delay = mpctx->audio_out->get_delay(); @@ -2097,12 +2019,12 @@ static int sleep_until_update(float *time_frame, float *aq_sleep_time) * sync to settle at the right value (but it eventually will.) * This settling time is very short for values below 100. */ - float predicted = mpctx->delay / playback_speed + *time_frame; + float predicted = mpctx->delay / opts->playback_speed + *time_frame; float difference = delay - predicted; delay = predicted + difference / (float)autosync; } - *time_frame = delay - mpctx->delay / playback_speed; + *time_frame = delay - mpctx->delay / opts->playback_speed; // delay = amount of audio buffered in soundcard/driver if (delay > 0.25) delay=0.25; else @@ -2127,26 +2049,27 @@ static int sleep_until_update(float *time_frame, float *aq_sleep_time) //============================== SLEEP: =================================== // flag 256 means: libvo driver does its timing (dvb card) - if (*time_frame > 0.001 && !(vo_flags&256)) - *time_frame = timing_sleep(*time_frame); + if (*time_frame > 0.001 && !(mpctx->sh_video->output_flags&256)) + *time_frame = timing_sleep(mpctx, *time_frame); return frame_time_remaining; } -int reinit_video_chain(void) { +int reinit_video_chain(struct MPContext *mpctx) +{ + struct MPOpts *opts = &mpctx->opts; sh_video_t * const sh_video = mpctx->sh_video; double ar=-1.0; //================== Init VIDEO (codec & libvo) ========================== - if(!fixed_vo || !(initialized_flags&INITIALIZED_VO)){ + if(opts->fixed_vo || !(mpctx->initialized_flags&INITIALIZED_VO)){ current_module="preinit_libvo"; //shouldn't we set dvideo->id=-2 when we fail? - vo_config_count=0; //if((mpctx->video_out->preinit(vo_subdevice))!=0){ - if(!(mpctx->video_out=init_best_video_out(video_driver_list))){ + if(!(mpctx->video_out=init_best_video_out(opts, mpctx->x11_state, mpctx->key_fifo, mpctx->input))){ mp_msg(MSGT_CPLAYER,MSGL_FATAL,MSGTR_ErrorInitializingVODevice); goto err_out; } - initialized_flags|=INITIALIZED_VO; + mpctx->initialized_flags|=INITIALIZED_VO; } if(stream_control(mpctx->demuxer->stream, STREAM_CTRL_GET_ASPECT_RATIO, &ar) != STREAM_UNSUPPORTED) @@ -2154,28 +2077,28 @@ int reinit_video_chain(void) { current_module="init_video_filters"; { char* vf_arg[] = { "_oldargs_", (char*)mpctx->video_out , NULL }; - sh_video->vfilter=(void*)vf_open_filter(NULL,"vo",vf_arg); + sh_video->vfilter = vf_open_filter(opts, NULL,"vo",vf_arg); } #ifdef CONFIG_MENU if(use_menu) { char* vf_arg[] = { "_oldargs_", menu_root, NULL }; - vf_menu = vf_open_plugin(libmenu_vfs,sh_video->vfilter,"menu",vf_arg); + vf_menu = vf_open_plugin(opts,libmenu_vfs,sh_video->vfilter,"menu",vf_arg); if(!vf_menu) { mp_msg(MSGT_CPLAYER,MSGL_ERR,MSGTR_CantOpenLibmenuFilterWithThisRootMenu,menu_root); use_menu = 0; } } if(vf_menu) - sh_video->vfilter=(void*)vf_menu; + sh_video->vfilter = vf_menu; #endif #ifdef CONFIG_ASS if(ass_enabled) { int i; int insert = 1; - if (vf_settings) - for (i = 0; vf_settings[i].name; ++i) - if (strcmp(vf_settings[i].name, "ass") == 0) { + if (opts->vf_settings) + for (i = 0; opts->vf_settings[i].name; ++i) + if (strcmp(opts->vf_settings[i].name, "ass") == 0) { insert = 0; break; } @@ -2183,20 +2106,20 @@ int reinit_video_chain(void) { extern vf_info_t vf_info_ass; const vf_info_t* libass_vfs[] = {&vf_info_ass, NULL}; char* vf_arg[] = {"auto", "1", NULL}; - vf_instance_t* vf_ass = vf_open_plugin(libass_vfs,sh_video->vfilter,"ass",vf_arg); + vf_instance_t* vf_ass = vf_open_plugin(opts, libass_vfs,sh_video->vfilter,"ass",vf_arg); if (vf_ass) - sh_video->vfilter=(void*)vf_ass; + sh_video->vfilter = vf_ass; else mp_msg(MSGT_CPLAYER,MSGL_ERR, "ASS: cannot add video filter\n"); } } #endif - sh_video->vfilter=(void*)append_filters(sh_video->vfilter); + sh_video->vfilter = append_filters(sh_video->vfilter, opts->vf_settings); #ifdef CONFIG_ASS if (ass_enabled) - ((vf_instance_t *)sh_video->vfilter)->control(sh_video->vfilter, VFCTRL_INIT_EOSD, ass_library); + sh_video->vfilter->control(sh_video->vfilter, VFCTRL_INIT_EOSD, ass_library); #endif current_module="init_video_codec"; @@ -2206,11 +2129,11 @@ int reinit_video_chain(void) { mp_msg(MSGT_CPLAYER,MSGL_INFO,"==========================================================================\n"); if(!sh_video->initialized){ - if(!fixed_vo) uninit_player(INITIALIZED_VO); + if(!opts->fixed_vo) uninit_player(mpctx, INITIALIZED_VO); goto err_out; } - initialized_flags|=INITIALIZED_VCODEC; + mpctx->initialized_flags|=INITIALIZED_VCODEC; if (sh_video->codec) mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_VIDEO_CODEC=%s\n", sh_video->codec->name); @@ -2239,87 +2162,185 @@ err_out: return 0; } -static double update_video(int *blit_frame) +static double update_video_nocorrect_pts(struct MPContext *mpctx, + int *blit_frame) { - sh_video_t * const sh_video = mpctx->sh_video; - //-------------------- Decode a frame: ----------------------- - double frame_time; - *blit_frame = 0; // Don't blit if we hit EOF - if (!correct_pts) { - unsigned char* start=NULL; - void *decoded_frame = NULL; - int drop_frame=0; - int in_size; - - current_module = "video_read_frame"; - frame_time = sh_video->next_frame_time; - in_size = video_read_frame(sh_video, &sh_video->next_frame_time, - &start, force_fps); + struct sh_video *sh_video = mpctx->sh_video; + *blit_frame = 0; + double frame_time = 0; + while (1) { + current_module = "filter_video"; + // In nocorrect-pts mode there is no way to properly time these frames + if (vf_output_queued_frame(sh_video->vfilter)) + break; + unsigned char *packet = NULL; + frame_time = sh_video->next_frame_time; + if (mpctx->update_video_immediately) + frame_time = 0; + int in_size = video_read_frame(sh_video, &sh_video->next_frame_time, + &packet, force_fps); + if (in_size < 0) { #ifdef CONFIG_DVDNAV - /// wait, still frame or EOF - if (mpctx->stream->type == STREAMTYPE_DVDNAV && in_size < 0) { - if (mp_dvdnav_is_eof(mpctx->stream)) return -1; - if (mpctx->d_video) mpctx->d_video->eof = 0; - if (mpctx->d_audio) mpctx->d_audio->eof = 0; - mpctx->stream->eof = 0; - } else -#endif - if (in_size < 0) - return -1; - if (in_size > max_framesize) - max_framesize = in_size; // stats - sh_video->timer += frame_time; - if (mpctx->sh_audio) - mpctx->delay -= frame_time; - // video_read_frame can change fps (e.g. for ASF video) - vo_fps = sh_video->fps; - drop_frame = check_framedrop(frame_time); - update_subtitles(sh_video, mpctx->d_sub, 0); - update_teletext(sh_video, mpctx->demuxer, 0); - update_osd_msg(); - current_module = "decode_video"; + if (mpctx->stream->type == STREAMTYPE_DVDNAV) { + if (mp_dvdnav_is_eof(mpctx->stream)) + return -1; + if (mpctx->d_video) + mpctx->d_video->eof = 0; + if (mpctx->d_audio) + mpctx->d_audio->eof = 0; + mpctx->stream->eof = 0; + } else +#endif + return -1; + } + if (in_size > max_framesize) + max_framesize = in_size; + sh_video->timer += frame_time; + if (mpctx->sh_audio) + mpctx->delay -= frame_time; + // video_read_frame can change fps (e.g. for ASF video) + vo_fps = sh_video->fps; + int framedrop_type = check_framedrop(mpctx, frame_time); + current_module = "decode video"; + + void *decoded_frame; #ifdef CONFIG_DVDNAV - decoded_frame = mp_dvdnav_restore_smpi(&in_size,&start,decoded_frame); - /// still frame has been reached, no need to decode - if (in_size > 0 && !decoded_frame) + decoded_frame = mp_dvdnav_restore_smpi(mpctx, &in_size, &packet, NULL); + if (in_size >= 0 && !decoded_frame) #endif - decoded_frame = decode_video(sh_video, start, in_size, drop_frame, - sh_video->pts); + decoded_frame = decode_video(sh_video, packet, in_size, framedrop_type, + sh_video->pts); #ifdef CONFIG_DVDNAV - /// save back last still frame for future display - mp_dvdnav_save_smpi(in_size,start,decoded_frame); -#endif - current_module = "filter_video"; - *blit_frame = (decoded_frame && filter_video(sh_video, decoded_frame, - sh_video->pts)); - } - else { - int res = generate_video_frame(sh_video, mpctx->d_video); - if (!res) - return -1; - ((vf_instance_t *)sh_video->vfilter)->control(sh_video->vfilter, - VFCTRL_GET_PTS, &sh_video->pts); - if (sh_video->pts == MP_NOPTS_VALUE) { - mp_msg(MSGT_CPLAYER, MSGL_ERR, "pts after filters MISSING\n"); - sh_video->pts = sh_video->last_pts; - } - if (sh_video->last_pts == MP_NOPTS_VALUE) - sh_video->last_pts= sh_video->pts; - else if (sh_video->last_pts > sh_video->pts) { - sh_video->last_pts = sh_video->pts; - mp_msg(MSGT_CPLAYER, MSGL_INFO, "pts value < previous\n"); - } - frame_time = sh_video->pts - sh_video->last_pts; - sh_video->last_pts = sh_video->pts; - sh_video->timer += frame_time; - if(mpctx->sh_audio) - mpctx->delay -= frame_time; - *blit_frame = res > 0; + // Save last still frame for future display + mp_dvdnav_save_smpi(mpctx, in_size, packet, decoded_frame); +#endif + if (decoded_frame) { + // These updates are done here for vf_expand OSD/subtitles + update_subtitles(sh_video, mpctx->d_sub, 0); + update_teletext(sh_video, mpctx->demuxer, 0); + update_osd_msg(mpctx); + current_module = "filter video"; + if (filter_video(sh_video, decoded_frame, sh_video->pts)) + break; + } } + *blit_frame = 1; + return frame_time; +} + +static double update_video(struct MPContext *mpctx, int *blit_frame) +{ + struct sh_video *sh_video = mpctx->sh_video; + *blit_frame = 0; + sh_video->vfilter->control(sh_video->vfilter, VFCTRL_SET_OSD_OBJ, + mpctx->osd); // hack for vf_expand + if (!mpctx->opts.correct_pts) + return update_video_nocorrect_pts(mpctx, blit_frame); + + double pts; + + while (1) { + current_module = "filter_video"; + // XXX Time used in this call is not counted in any performance + // timer now, OSD time is not updated correctly for filter-added frames + if (vf_output_queued_frame(sh_video->vfilter)) + break; + unsigned char *packet = NULL; + bool hit_eof = false; + int in_size = ds_get_packet_pts(mpctx->d_video, &packet, &pts); + if (in_size < 0) { + // try to extract last frames in case of decoder lag + in_size = 0; + pts = 1e300; + hit_eof = true; + } + if (in_size > max_framesize) + max_framesize = in_size; + current_module = "decode video"; + int framedrop_type = check_framedrop(mpctx, sh_video->frametime); + void *decoded_frame = decode_video(sh_video, packet, in_size, + framedrop_type, pts); + if (decoded_frame) { + // These updates are done here for vf_expand OSD/subtitles + update_subtitles(sh_video, mpctx->d_sub, 0); + update_teletext(sh_video, mpctx->demuxer, 0); + update_osd_msg(mpctx); + current_module = "filter video"; + if (filter_video(sh_video, decoded_frame, sh_video->pts)) + break; + } else if (hit_eof) + return -1; + } + + sh_video->vfilter->control(sh_video->vfilter, VFCTRL_GET_PTS, &pts); + if (pts == MP_NOPTS_VALUE) { + mp_msg(MSGT_CPLAYER, MSGL_ERR, "Video pts after filters MISSING\n"); + // Try to use decoder pts from before filters + pts = sh_video->pts; + } + sh_video->pts = pts; + if (sh_video->last_pts == MP_NOPTS_VALUE) + sh_video->last_pts = sh_video->pts; + else if (sh_video->last_pts > sh_video->pts) { + mp_msg(MSGT_CPLAYER, MSGL_INFO, "Decreasing video pts: %f < %f\n", + sh_video->pts, sh_video->last_pts); + /* If the difference in pts is small treat it as jitter around the + * right value (possibly caused by incorrect timestamp ordering) and + * just show this frame immediately after the last one. + * Treat bigger differences as timestamp resets and start counting + * timing of later frames from the position of this one. */ + if (sh_video->last_pts - sh_video->pts > 0.5) + sh_video->last_pts = sh_video->pts; + else + sh_video->pts = sh_video->last_pts; + } + double frame_time = sh_video->pts - sh_video->last_pts; + sh_video->last_pts = sh_video->pts; + sh_video->timer += frame_time; + if (mpctx->sh_audio) + mpctx->delay -= frame_time; + *blit_frame = 1; return frame_time; } -static void pause_loop(void) +void pause_player(struct MPContext *mpctx) +{ + if (mpctx->paused) + return; + mpctx->paused = 1; + mpctx->step_frames = 0; + mpctx->time_frame -= get_relative_time(mpctx); + + if (mpctx->video_out && mpctx->sh_video && mpctx->video_out->config_ok) + vo_control(mpctx->video_out, VOCTRL_PAUSE, NULL); + + if (mpctx->audio_out && mpctx->sh_audio) + mpctx->audio_out->pause(); // pause audio, keep data if possible +} + +void unpause_player(struct MPContext *mpctx) +{ + if (!mpctx->paused) + return; + mpctx->paused = 0; + + if (mpctx->audio_out && mpctx->sh_audio) + mpctx->audio_out->resume(); // resume audio + if (mpctx->video_out && mpctx->sh_video && mpctx->video_out->config_ok + && !mpctx->step_frames) + vo_control(mpctx->video_out, VOCTRL_RESUME, NULL); // resume video + (void)get_relative_time(mpctx); // ignore time that passed during pause +} + +void add_step_frame(struct MPContext *mpctx) +{ + mpctx->step_frames++; + if (mpctx->video_out && mpctx->sh_video && mpctx->video_out->config_ok) + vo_control(mpctx->video_out, VOCTRL_PAUSE, NULL); + unpause_player(mpctx); +} + +static void pause_loop(struct MPContext *mpctx) { mp_cmd_t* cmd; if (!quiet) { @@ -2331,7 +2352,7 @@ static void pause_loop(void) int mlen = strlen(msg); msg[mlen-1] = '\0'; set_osd_msg(OSD_MSG_PAUSE, 1, 0, "%s", msg+1); - update_osd_msg(); + update_osd_msg(mpctx); } else mp_msg(MSGT_CPLAYER,MSGL_STATUS,MSGTR_Paused); mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_PAUSED\n"); @@ -2340,27 +2361,22 @@ static void pause_loop(void) if (use_gui) guiGetEvent(guiCEvent, (char *)guiSetPause); #endif - if (mpctx->video_out && mpctx->sh_video && vo_config_count) - mpctx->video_out->control(VOCTRL_PAUSE, NULL); - - if (mpctx->audio_out && mpctx->sh_audio) - mpctx->audio_out->pause(); // pause audio, keep data if possible - while ( (cmd = mp_input_get_cmd(20, 1, 1)) == NULL + while ( (cmd = mp_input_get_cmd(mpctx->input, 20, 1, 1)) == NULL || cmd->id == MP_CMD_SET_MOUSE_POS || cmd->pausing == 4) { if (cmd) { - cmd = mp_input_get_cmd(0,1,0); + cmd = mp_input_get_cmd(mpctx->input, 0,1,0); run_command(mpctx, cmd); mp_cmd_free(cmd); continue; } - if (mpctx->sh_video && mpctx->video_out && vo_config_count) - mpctx->video_out->check_events(); + if (mpctx->sh_video && mpctx->video_out) + vo_check_events(mpctx->video_out); #ifdef CONFIG_GUI if (use_gui) { guiEventHandling(); guiGetEvent(guiReDraw, NULL); - if (guiIntfStruct.Playing!=2 || (rel_seek_secs || abs_seek_pos)) + if (guiIntfStruct.Playing!=2 || (mpctx->rel_seek_secs || mpctx->abs_seek_pos)) break; } #endif @@ -2369,17 +2385,12 @@ static void pause_loop(void) vf_menu_pause_update(vf_menu); #endif usec_sleep(20000); + update_osd_msg(mpctx); + int hack = vo_osd_changed(0); + vo_osd_changed(hack); + if (hack) + break; } - if (cmd && cmd->id == MP_CMD_PAUSE) { - cmd = mp_input_get_cmd(0,1,0); - mp_cmd_free(cmd); - } - mpctx->osd_function=OSD_PLAY; - if (mpctx->audio_out && mpctx->sh_audio) - mpctx->audio_out->resume(); // resume audio - if (mpctx->video_out && mpctx->sh_video && vo_config_count) - mpctx->video_out->control(VOCTRL_RESUME, NULL); // resume video - (void)GetRelativeTime(); // ignore time that passed during pause #ifdef CONFIG_GUI if (use_gui) { if (guiIntfStruct.Playing == guiSetStop) @@ -2427,8 +2438,8 @@ static void edl_update(MPContext *mpctx) if (mpctx->sh_video->pts >= next_edl_record->start_sec) { if (next_edl_record->action == EDL_SKIP) { mpctx->osd_function = OSD_FFW; - abs_seek_pos = 0; - rel_seek_secs = next_edl_record->length_sec; + mpctx->abs_seek_pos = 0; + mpctx->rel_seek_secs = next_edl_record->length_sec; mp_msg(MSGT_CPLAYER, MSGL_DBG4, "EDL_SKIP: start [%f], stop " "[%f], length [%f]\n", next_edl_record->start_sec, next_edl_record->stop_sec, next_edl_record->length_sec); @@ -2458,12 +2469,14 @@ static int seek(MPContext *mpctx, double amount, int style) if (mpctx->sh_video) { current_module = "seek_video_reset"; resync_video_stream(mpctx->sh_video); - if (vo_config_count) - mpctx->video_out->control(VOCTRL_RESET, NULL); + if (mpctx->video_out->config_ok) + vo_control(mpctx->video_out, VOCTRL_RESET, NULL); mpctx->sh_video->num_buffered_pts = 0; mpctx->sh_video->last_pts = MP_NOPTS_VALUE; mpctx->num_buffered_frames = 0; mpctx->delay = 0; + mpctx->time_frame = 0; + mpctx->update_video_immediately = true; // Not all demuxers set d_video->pts during seek, so this value // (which is used by at least vobsub and edl code below) may // be completely wrong (probably 0). @@ -2486,8 +2499,7 @@ static int seek(MPContext *mpctx, double amount, int style) edl_seek_reset(mpctx); - c_total = 0; - max_pts_correction = 0.1; + mpctx->total_avsync_change = 0; audio_time_usage = 0; video_time_usage = 0; vout_time_usage = 0; drop_frame_cnt = 0; @@ -2495,6 +2507,14 @@ static int seek(MPContext *mpctx, double amount, int style) return 0; } + +static int read_keys(void *ctx, int fd) +{ + getch2(ctx); + return mplayer_get_key(ctx, 0); +} + + /* This preprocessor directive is a hack to generate a mplayer-nomain.o object * file for some tools to link against. */ #ifndef DISABLE_MAIN @@ -2514,18 +2534,33 @@ int i; int gui_no_filename=0; + struct MPContext *mpctx = &(struct MPContext){ + .osd_function = OSD_PLAY, + .begin_skip = MP_NOPTS_VALUE, + .play_tree_step = 1, + .global_sub_pos = -1, + .set_of_sub_pos = -1, + .file_format = DEMUXER_TYPE_UNKNOWN, + .last_dvb_step = 1, + }; + InitTimer(); srand(GetTimerMS()); mp_msg_init(); +#ifdef CONFIG_X11 + mpctx->x11_state = vo_x11_init_state(); +#endif + struct MPOpts *opts = &mpctx->opts; + set_default_mplayer_options(opts); // Create the config context and register the options - mconfig = m_config_new(); - m_config_register_options(mconfig,mplayer_opts); - mp_input_register_options(mconfig); + mpctx->mconfig = m_config_new(opts, cfg_include); + m_config_register_options(mpctx->mconfig,mplayer_opts); + mp_input_register_options(mpctx->mconfig); // Preparse the command line - m_config_preparse_command_line(mconfig,argc,argv); + m_config_preparse_command_line(mpctx->mconfig,argc,argv); print_version("MPlayer"); #if (defined(__MINGW32__) || defined(__CYGWIN__)) && defined(CONFIG_WIN32DLL) @@ -2551,36 +2586,37 @@ int gui_no_filename=0; use_gui=1; } - parse_cfgfiles(mconfig); + parse_cfgfiles(mpctx, mpctx->mconfig); #ifdef CONFIG_GUI if ( use_gui ) cfg_read(); #endif - mpctx->playtree = m_config_parse_mp_command_line(mconfig, argc, argv); + mpctx->playtree = m_config_parse_mp_command_line(mpctx->mconfig, argc, argv); if(mpctx->playtree == NULL) opt_exit = 1; else { mpctx->playtree = play_tree_cleanup(mpctx->playtree); if(mpctx->playtree) { - mpctx->playtree_iter = play_tree_iter_new(mpctx->playtree,mconfig); + mpctx->playtree_iter = play_tree_iter_new(mpctx->playtree,mpctx->mconfig); if(mpctx->playtree_iter) { if(play_tree_iter_step(mpctx->playtree_iter,0,0) != PLAY_TREE_ITER_ENTRY) { play_tree_iter_free(mpctx->playtree_iter); mpctx->playtree_iter = NULL; } - filename = play_tree_iter_get_file(mpctx->playtree_iter,1); + mpctx->filename = play_tree_iter_get_file(mpctx->playtree_iter,1); } } } + mpctx->key_fifo = mp_fifo_create(opts); #if (defined(__MINGW32__) || defined(__CYGWIN__)) && defined(CONFIG_GUI) void *runningmplayer = FindWindow("MPlayer GUI for Windows", "MPlayer for Windows"); - if(runningmplayer && filename && use_gui){ + if(runningmplayer && mpctx->filename && use_gui){ COPYDATASTRUCT csData; char file[MAX_PATH]; - char *filepart = filename; - if(GetFullPathName(filename, MAX_PATH, file, &filepart)){ + char *filepart = mpctx->filename; + if(GetFullPathName(mpctx->filename, MAX_PATH, file, &filepart)){ csData.dwData = 0; csData.cbData = strlen(file)*2; csData.lpData = file; @@ -2625,16 +2661,16 @@ int gui_no_filename=0; play_tree_add_bpf(mpctx->playtree, cwd); } // Import initital playtree into GUI. - import_initial_playtree_into_gui(mpctx->playtree, mconfig, enqueue); + import_initial_playtree_into_gui(mpctx->playtree, mpctx->mconfig, enqueue); } #endif /* CONFIG_GUI */ - if(video_driver_list && strcmp(video_driver_list[0],"help")==0){ + if(opts->video_driver_list && strcmp(opts->video_driver_list[0],"help")==0){ list_video_out(); opt_exit = 1; } - if(audio_driver_list && strcmp(audio_driver_list[0],"help")==0){ + if(opts->audio_driver_list && strcmp(opts->audio_driver_list[0],"help")==0){ list_audio_out(); opt_exit = 1; } @@ -2644,7 +2680,7 @@ if(!codecs_file || !parse_codec_cfg(codecs_file)){ if(!parse_codec_cfg(mem_ptr=get_path("codecs.conf"))){ if(!parse_codec_cfg(MPLAYER_CONFDIR "/codecs.conf")){ if(!parse_codec_cfg(NULL)){ - exit_player_with_rc(EXIT_NONE, 0); + exit_player_with_rc(mpctx, EXIT_NONE, 0); } mp_msg(MSGT_CPLAYER,MSGL_V,MSGTR_BuiltinCodecsConf); } @@ -2709,18 +2745,18 @@ if(!codecs_file || !parse_codec_cfg(codecs_file)){ } if(opt_exit) - exit_player(EXIT_NONE); + exit_player(mpctx, EXIT_NONE); if (player_idle_mode && use_gui) { mp_msg(MSGT_CPLAYER, MSGL_FATAL, MSGTR_NoIdleAndGui); - exit_player_with_rc(EXIT_NONE, 1); + exit_player_with_rc(mpctx, EXIT_NONE, 1); } - if(!filename && !player_idle_mode){ + if(!mpctx->filename && !player_idle_mode){ if(!use_gui){ // no file/vcd/dvd -> show HELP: mp_msg(MSGT_CPLAYER, MSGL_INFO, help_text); - exit_player_with_rc(EXIT_NONE, 0); + exit_player_with_rc(mpctx, EXIT_NONE, 0); } else gui_no_filename=1; } @@ -2736,6 +2772,8 @@ if(!codecs_file || !parse_codec_cfg(codecs_file)){ //------ load global data first ------ + mpctx->osd = osd_create(); + // check font #ifdef CONFIG_FREETYPE init_freetype(); @@ -2757,16 +2795,14 @@ if(!codecs_file || !parse_codec_cfg(codecs_file)){ vo_font=read_font_desc(MPLAYER_DATADIR "/font/font.desc",font_factor,verbose>1); } if (sub_font_name) - sub_font = read_font_desc(sub_font_name, font_factor, verbose>1); + mpctx->osd->sub_font = read_font_desc(sub_font_name, font_factor, verbose>1); else - sub_font = vo_font; + mpctx->osd->sub_font = vo_font; #endif #ifdef CONFIG_FONTCONFIG } #endif - vo_init_osd(); - #ifdef CONFIG_ASS ass_library = ass_init(); #endif @@ -2813,25 +2849,26 @@ if(!codecs_file || !parse_codec_cfg(codecs_file)){ // Init input system current_module = "init_input"; -mp_input_init(use_gui); - mp_input_add_key_fd(-1,0,mplayer_get_key,NULL); + mpctx->input = mp_input_init(&opts->input, use_gui); + mp_input_add_key_fd(mpctx->input, -1,0,mplayer_get_key,NULL, mpctx->key_fifo); if(slave_mode) - mp_input_add_cmd_fd(0,USE_SELECT,MP_INPUT_SLAVE_CMD_FUNC,NULL); + mp_input_add_cmd_fd(mpctx->input, 0,USE_SELECT,MP_INPUT_SLAVE_CMD_FUNC,NULL); else if(!noconsolecontrols) - mp_input_add_event_fd(0, getch2); + mp_input_add_key_fd(mpctx->input, 0, 1, read_keys, NULL, mpctx->key_fifo); // Set the libstream interrupt callback -stream_set_interrupt_callback(mp_input_check_interrupt); +stream_set_interrupt_callback(mp_input_check_interrupt, mpctx->input); #ifdef CONFIG_MENU if(use_menu) { - if(menu_cfg && menu_init(mpctx, menu_cfg)) + if(menu_cfg && menu_init(mpctx, mpctx->mconfig, mpctx->input, menu_cfg)) mp_msg(MSGT_CPLAYER,MSGL_INFO,MSGTR_MenuInitialized, menu_cfg); else { menu_cfg = get_path("menu.conf"); - if(menu_init(mpctx, menu_cfg)) + if(menu_init(mpctx, mpctx->mconfig, mpctx->input, menu_cfg)) mp_msg(MSGT_CPLAYER,MSGL_INFO,MSGTR_MenuInitialized, menu_cfg); else { - if(menu_init(mpctx, MPLAYER_CONFDIR "/menu.conf")) + if(menu_init(mpctx, mpctx->mconfig, mpctx->input, + MPLAYER_CONFDIR "/menu.conf")) mp_msg(MSGT_CPLAYER,MSGL_INFO,MSGTR_MenuInitialized, MPLAYER_CONFDIR"/menu.conf"); else { mp_msg(MSGT_CPLAYER,MSGL_INFO,MSGTR_MenuInitFailed); @@ -2842,7 +2879,6 @@ stream_set_interrupt_callback(mp_input_check_interrupt); } #endif -initialized_flags|=INITIALIZED_INPUT; current_module = NULL; /// Catch signals @@ -2879,7 +2915,7 @@ current_module = NULL; if(use_gui){ guiInit(); guiGetEvent(guiSetContext, mpctx); - initialized_flags|=INITIALIZED_GUI; + mpctx->initialized_flags|=INITIALIZED_GUI; guiGetEvent( guiCEvent,(char *)((gui_no_filename) ? 0 : 1) ); } #endif @@ -2892,25 +2928,25 @@ play_next_file: mpctx->global_sub_size = 0; { int i; for (i = 0; i < SUB_SOURCES; i++) mpctx->global_sub_indices[i] = -1; } - if (filename) { - load_per_protocol_config (mconfig, filename); - load_per_extension_config (mconfig, filename); - load_per_file_config (mconfig, filename); + if (mpctx->filename) { + load_per_protocol_config (mpctx->mconfig, mpctx->filename); + load_per_extension_config (mpctx->mconfig, mpctx->filename); + load_per_file_config (mpctx->mconfig, mpctx->filename); } - if (video_driver_list) - load_per_output_config (mconfig, PROFILE_CFG_VO, video_driver_list[0]); - if (audio_driver_list) - load_per_output_config (mconfig, PROFILE_CFG_AO, audio_driver_list[0]); + if (opts->video_driver_list) + load_per_output_config (mpctx->mconfig, PROFILE_CFG_VO, opts->video_driver_list[0]); + if (opts->audio_driver_list) + load_per_output_config (mpctx->mconfig, PROFILE_CFG_AO, opts->audio_driver_list[0]); // We must enable getch2 here to be able to interrupt network connection // or cache filling if(!noconsolecontrols && !slave_mode){ - if(initialized_flags&INITIALIZED_GETCH2) + if(mpctx->initialized_flags&INITIALIZED_GETCH2) mp_msg(MSGT_CPLAYER,MSGL_WARN,MSGTR_Getch2InitializedTwice); else getch2_enable(); // prepare stdin for hotkeys... - initialized_flags|=INITIALIZED_GETCH2; + mpctx->initialized_flags|=INITIALIZED_GETCH2; mp_msg(MSGT_CPLAYER,MSGL_DBG2,"\n[[[init getch2]]]\n"); } @@ -2925,7 +2961,7 @@ if(!noconsolecontrols && !slave_mode){ usec_sleep(20000); guiEventHandling(); guiGetEvent( guiReDraw,NULL ); - if ( (cmd = mp_input_get_cmd(0,0,0)) != NULL) { + if ( (cmd = mp_input_get_cmd(mpctx->input, 0,0,0)) != NULL) { guiGetEvent(guiIEvent, (char *)cmd->id); mp_cmd_free(cmd); } @@ -2940,7 +2976,7 @@ if(!noconsolecontrols && !slave_mode){ play_tree_set_child( mpctx->playtree,entry ); if(mpctx->playtree) { - mpctx->playtree_iter = play_tree_iter_new(mpctx->playtree,mconfig); + mpctx->playtree_iter = play_tree_iter_new(mpctx->playtree,mpctx->mconfig); if(mpctx->playtree_iter) { if(play_tree_iter_step(mpctx->playtree_iter,0,0) != PLAY_TREE_ITER_ENTRY) @@ -2948,18 +2984,19 @@ if(!noconsolecontrols && !slave_mode){ play_tree_iter_free(mpctx->playtree_iter); mpctx->playtree_iter = NULL; } - filename = play_tree_iter_get_file(mpctx->playtree_iter,1); + mpctx->filename = play_tree_iter_get_file(mpctx->playtree_iter,1); } } } } #endif /* CONFIG_GUI */ -while (player_idle_mode && !filename) { +while (player_idle_mode && !mpctx->filename) { play_tree_t * entry = NULL; mp_cmd_t * cmd; - while (!(cmd = mp_input_get_cmd(0,1,0))) { // wait for command - if (mpctx->video_out && vo_config_count) mpctx->video_out->check_events(); + while (!(cmd = mp_input_get_cmd(mpctx->input, 0,1,0))) { // wait for command + if (mpctx->video_out) + vo_check_events(mpctx->video_out); usec_sleep(20000); } switch (cmd->id) { @@ -2970,10 +3007,10 @@ while (player_idle_mode && !filename) { // The entry is added to the main playtree after the switch(). break; case MP_CMD_LOADLIST: - entry = parse_playlist_file(cmd->args[0].v.s); + entry = parse_playlist_file(mpctx->mconfig, cmd->args[0].v.s); break; case MP_CMD_QUIT: - exit_player_with_rc(EXIT_QUIT, (cmd->nargs > 0)? cmd->args[0].v.i : 0); + exit_player_with_rc(mpctx, EXIT_QUIT, (cmd->nargs > 0)? cmd->args[0].v.i : 0); break; case MP_CMD_GET_PROPERTY: case MP_CMD_SET_PROPERTY: @@ -2994,7 +3031,7 @@ while (player_idle_mode && !filename) { play_tree_set_child(mpctx->playtree, entry); /* Make iterator start at the top the of tree. */ - mpctx->playtree_iter = play_tree_iter_new(mpctx->playtree, mconfig); + mpctx->playtree_iter = play_tree_iter_new(mpctx->playtree, mpctx->mconfig); if (!mpctx->playtree_iter) continue; // find the first real item in the tree @@ -3004,14 +3041,14 @@ while (player_idle_mode && !filename) { mpctx->playtree_iter = NULL; continue; // wait for next command } - filename = play_tree_iter_get_file(mpctx->playtree_iter, 1); + mpctx->filename = play_tree_iter_get_file(mpctx->playtree_iter, 1); } } //--------------------------------------------------------------------------- - if(filename) + if(mpctx->filename) mp_msg(MSGT_CPLAYER,MSGL_INFO,MSGTR_Playing, - filename_recode(filename)); + filename_recode(mpctx->filename)); if (edl_filename) { if (edl_records) free_edl(edl_records); @@ -3034,9 +3071,9 @@ if (edl_output_filename) { if(vo_vobsub==NULL) mp_msg(MSGT_CPLAYER,MSGL_ERR,MSGTR_CantLoadSub, filename_recode(vobsub_name)); - } else if (sub_auto && filename){ + } else if (sub_auto && mpctx->filename){ /* try to autodetect vobsub from movie filename ::atmos */ - char *buf = strdup(filename), *psub; + char *buf = strdup(mpctx->filename), *psub; char *pdot = strrchr(buf, '.'); char *pslash = strrchr(buf, '/'); #if defined(__MINGW32__) || defined(__CYGWIN__) @@ -3064,7 +3101,7 @@ if (edl_output_filename) { free(buf); } if(vo_vobsub){ - initialized_flags|=INITIALIZED_VOBSUB; + mpctx->initialized_flags|=INITIALIZED_VOBSUB; vobsub_set_from_lang(vo_vobsub, dvdsub_lang); // setup global sub numbering @@ -3088,26 +3125,32 @@ if (edl_output_filename) { mpctx->sh_video=NULL; current_module="open_stream"; - mpctx->stream=open_stream(filename,0,&mpctx->file_format); + mpctx->stream = open_stream(mpctx->filename, opts, &mpctx->file_format); if(!mpctx->stream) { // error... - mpctx->eof = libmpdemux_was_interrupted(PT_NEXT_ENTRY); + mpctx->stop_play = libmpdemux_was_interrupted(mpctx, PT_NEXT_ENTRY); goto goto_next_file; } - initialized_flags|=INITIALIZED_STREAM; + mpctx->initialized_flags|=INITIALIZED_STREAM; #ifdef CONFIG_GUI if ( use_gui ) guiGetEvent( guiSetStream,(char *)mpctx->stream ); #endif if(mpctx->file_format == DEMUXER_TYPE_PLAYLIST) { + mp_msg(MSGT_CPLAYER, MSGL_ERR, "\nThis looks like a playlist, but " + "playlist support will not be used automatically.\n" + "MPlayer's playlist code is unsafe and should only be used with " + "trusted sources.\nPlayback will probably fail.\n\n"); +#if 0 play_tree_t* entry; // Handle playlist current_module="handle_playlist"; mp_msg(MSGT_CPLAYER,MSGL_V,"Parsing playlist %s...\n", - filename_recode(filename)); - entry = parse_playtree(mpctx->stream,0); - mpctx->eof=playtree_add_playlist(entry); + filename_recode(mpctx->filename)); + entry = parse_playtree(mpctx->stream, mpctx->mconfig, 0); + mpctx->eof=playtree_add_playlist(mpctx, entry); goto goto_next_file; +#endif } mpctx->stream->start_pos+=seek_to_byte; @@ -3118,14 +3161,14 @@ if(stream_dump_type==5){ current_module="dumpstream"; if(mpctx->stream->type==STREAMTYPE_STREAM && mpctx->stream->fd<0){ mp_msg(MSGT_CPLAYER,MSGL_FATAL,MSGTR_DumpstreamFdUnavailable); - exit_player(EXIT_ERROR); + exit_player(mpctx, EXIT_ERROR); } stream_reset(mpctx->stream); stream_seek(mpctx->stream,mpctx->stream->start_pos); f=fopen(stream_dump_name,"wb"); if(!f){ mp_msg(MSGT_CPLAYER,MSGL_FATAL,MSGTR_CantOpenDumpfile); - exit_player(EXIT_ERROR); + exit_player(mpctx, EXIT_ERROR); } if (dvd_chapter > 1) { int chapter = dvd_chapter - 1; @@ -3136,7 +3179,7 @@ if(stream_dump_type==5){ if(len>0) { if(fwrite(buf,len,1,f) != 1) { mp_msg(MSGT_MENCODER,MSGL_FATAL,MSGTR_ErrorWritingFile,stream_dump_name); - exit_player(EXIT_ERROR); + exit_player(mpctx, EXIT_ERROR); } } if(dvd_last_chapter > 0) { @@ -3148,18 +3191,18 @@ if(stream_dump_type==5){ } if(fclose(f)) { mp_msg(MSGT_MENCODER,MSGL_FATAL,MSGTR_ErrorWritingFile,stream_dump_name); - exit_player(EXIT_ERROR); + exit_player(mpctx, EXIT_ERROR); } mp_msg(MSGT_CPLAYER,MSGL_INFO,MSGTR_CoreDumped); - exit_player_with_rc(EXIT_EOF, 0); + exit_player_with_rc(mpctx, EXIT_EOF, 0); } #ifdef CONFIG_DVDREAD if(mpctx->stream->type==STREAMTYPE_DVD){ current_module="dvd lang->id"; - if(audio_id==-1) audio_id=dvd_aid_from_lang(mpctx->stream,audio_lang); - if(dvdsub_lang && dvdsub_id==-2) dvdsub_id=-1; - if(dvdsub_lang && dvdsub_id==-1) dvdsub_id=dvd_sid_from_lang(mpctx->stream,dvdsub_lang); + if(opts->audio_id==-1) opts->audio_id=dvd_aid_from_lang(mpctx->stream,audio_lang); + if(dvdsub_lang && opts->sub_id==-2) opts->sub_id=-1; + if(dvdsub_lang && opts->sub_id==-1) opts->sub_id=dvd_sid_from_lang(mpctx->stream,dvdsub_lang); // setup global sub numbering mpctx->global_sub_indices[SUB_SOURCE_DEMUX] = mpctx->global_sub_size; // the global # of the first demux-specific sub. mpctx->global_sub_size += dvd_number_of_subs(mpctx->stream); @@ -3170,9 +3213,9 @@ if(mpctx->stream->type==STREAMTYPE_DVD){ #ifdef CONFIG_DVDNAV if(mpctx->stream->type==STREAMTYPE_DVDNAV){ current_module="dvdnav lang->id"; - if(audio_id==-1) audio_id=mp_dvdnav_aid_from_lang(mpctx->stream,audio_lang); - if(dvdsub_lang && dvdsub_id==-2) dvdsub_id=-1; - if(dvdsub_lang && dvdsub_id==-1) dvdsub_id=mp_dvdnav_sid_from_lang(mpctx->stream,dvdsub_lang); + if(opts->audio_id==-1) opts->audio_id=mp_dvdnav_aid_from_lang(mpctx->stream,audio_lang); + if(dvdsub_lang && opts->sub_id==-2) opts->sub_id=-1; + if(dvdsub_lang && opts->sub_id==-1) opts->sub_id=mp_dvdnav_sid_from_lang(mpctx->stream,dvdsub_lang); // setup global sub numbering mpctx->global_sub_indices[SUB_SOURCE_DEMUX] = mpctx->global_sub_size; // the global # of the first demux-specific sub. mpctx->global_sub_size += mp_dvdnav_number_of_subs(mpctx->stream); @@ -3187,13 +3230,13 @@ if(stream_cache_size>0){ if(!stream_enable_cache(mpctx->stream,stream_cache_size*1024, stream_cache_size*1024*(stream_cache_min_percent / 100.0), stream_cache_size*1024*(stream_cache_seek_min_percent / 100.0))) - if((mpctx->eof = libmpdemux_was_interrupted(PT_NEXT_ENTRY))) goto goto_next_file; + if((mpctx->stop_play = libmpdemux_was_interrupted(mpctx, PT_NEXT_ENTRY))) goto goto_next_file; } //============ Open DEMUXERS --- DETECT file type ======================= current_module="demux_open"; -mpctx->demuxer=demux_open(mpctx->stream,mpctx->file_format,audio_id,video_id,dvdsub_id,filename); +mpctx->demuxer=demux_open(opts, mpctx->stream,mpctx->file_format,opts->audio_id,opts->video_id,opts->sub_id,mpctx->filename); // HACK to get MOV Reference Files working @@ -3214,18 +3257,18 @@ if (mpctx->demuxer && mpctx->demuxer->type==DEMUXER_TYPE_PLAYLIST) if ((strlen(bname)>10) && !strncmp(bname,"qt",2) && !strncmp(bname+3,"gateQT",6)) continue; - if (!strncmp(bname,mp_basename(filename),strlen(bname))) // ignoring self-reference + if (!strncmp(bname,mp_basename(mpctx->filename),strlen(bname))) // ignoring self-reference continue; entry = play_tree_new(); - if (filename && !strcmp(mp_basename(playlist_entry),playlist_entry)) // add reference path of current file + if (mpctx->filename && !strcmp(mp_basename(playlist_entry),playlist_entry)) // add reference path of current file { - temp=malloc((strlen(filename)-strlen(mp_basename(filename))+strlen(playlist_entry)+1)); + temp=malloc((strlen(mpctx->filename)-strlen(mp_basename(mpctx->filename))+strlen(playlist_entry)+1)); if (temp) { - strncpy(temp, filename, strlen(filename)-strlen(mp_basename(filename))); - temp[strlen(filename)-strlen(mp_basename(filename))]='\0'; + strncpy(temp, mpctx->filename, strlen(mpctx->filename)-strlen(mp_basename(mpctx->filename))); + temp[strlen(mpctx->filename)-strlen(mp_basename(mpctx->filename))]='\0'; strcat(temp, playlist_entry); play_tree_add_file(entry,temp); mp_msg(MSGT_CPLAYER,MSGL_V,"Resolving reference to %s.\n",temp); @@ -3247,7 +3290,7 @@ if (mpctx->demuxer && mpctx->demuxer->type==DEMUXER_TYPE_PLAYLIST) { entry = play_tree_new(); play_tree_set_child(entry,list); - mpctx->eof=playtree_add_playlist(entry); + mpctx->stop_play = playtree_add_playlist(mpctx, entry); goto goto_next_file; } } @@ -3260,7 +3303,7 @@ if(dvd_chapter>1) { seek(mpctx, pts, SEEK_ABSOLUTE); } -initialized_flags|=INITIALIZED_DEMUXER; +mpctx->initialized_flags|=INITIALIZED_DEMUXER; if (mpctx->stream->type != STREAMTYPE_DVD && mpctx->stream->type != STREAMTYPE_DVDNAV) { int i; @@ -3269,12 +3312,12 @@ if (mpctx->stream->type != STREAMTYPE_DVD && mpctx->stream->type != STREAMTYPE_D mpctx->global_sub_indices[SUB_SOURCE_DEMUX] = mpctx->global_sub_size; // the global # of the first demux-specific sub. for (i = 0; i < MAX_S_STREAMS; i++) if (mpctx->demuxer->s_streams[i]) - maxid = FFMAX(maxid, ((sh_sub_t *)mpctx->demuxer->s_streams[i])->sid); + maxid = FFMAX(maxid, mpctx->demuxer->s_streams[i]->sid); mpctx->global_sub_size += maxid + 1; } -// Make dvdsub_id always selectable if set. -if (mpctx->global_sub_size <= mpctx->global_sub_indices[SUB_SOURCE_DEMUX] + dvdsub_id) - mpctx->global_sub_size = mpctx->global_sub_indices[SUB_SOURCE_DEMUX] + dvdsub_id + 1; +// Make opts->sub_id always selectable if set. +if (mpctx->global_sub_size <= mpctx->global_sub_indices[SUB_SOURCE_DEMUX] + opts->sub_id) + mpctx->global_sub_size = mpctx->global_sub_indices[SUB_SOURCE_DEMUX] + opts->sub_id + 1; #ifdef CONFIG_ASS if (ass_enabled && ass_library) { @@ -3298,7 +3341,7 @@ mpctx->d_video=mpctx->demuxer->video; mpctx->d_sub=mpctx->demuxer->sub; // select audio stream -select_audio(mpctx->demuxer, audio_id, audio_lang); +select_audio(mpctx->demuxer, opts->audio_id, audio_lang); // DUMP STREAMS: if((stream_dump_type)&&(stream_dump_type<4)){ @@ -3313,7 +3356,7 @@ if((stream_dump_type)&&(stream_dump_type<4)){ } if(!ds){ mp_msg(MSGT_CPLAYER,MSGL_FATAL,MSGTR_DumpSelectedStreamMissing); - exit_player(EXIT_ERROR); + exit_player(mpctx, EXIT_ERROR); } // disable other streams: if(mpctx->d_audio && mpctx->d_audio!=ds) {ds_free_packs(mpctx->d_audio); mpctx->d_audio->id=-2; } @@ -3323,7 +3366,7 @@ if((stream_dump_type)&&(stream_dump_type<4)){ f=fopen(stream_dump_name,"wb"); if(!f){ mp_msg(MSGT_CPLAYER,MSGL_FATAL,MSGTR_CantOpenDumpfile); - exit_player(EXIT_ERROR); + exit_player(mpctx, EXIT_ERROR); } while(!ds->eof){ unsigned char* start; @@ -3339,7 +3382,7 @@ if((stream_dump_type)&&(stream_dump_type<4)){ } fclose(f); mp_msg(MSGT_CPLAYER,MSGL_INFO,MSGTR_CoreDumped); - exit_player_with_rc(EXIT_EOF, 0); + exit_player_with_rc(mpctx, EXIT_EOF, 0); } mpctx->sh_audio=mpctx->d_audio->sh; @@ -3384,8 +3427,10 @@ if(!mpctx->sh_video && !mpctx->sh_audio){ else dir = DVB_CHANNEL_LOWER; - if(dvb_step_channel(mpctx->stream, dir)) - mpctx->eof = mpctx->dvbin_reopen = 1; + if(dvb_step_channel(mpctx->stream, dir)) { + mpctx->stop_play = PT_NEXT_ENTRY; + mpctx->dvbin_reopen = 1; + } } #endif goto goto_next_file; // exit_player(MSGTR_Exit_error); @@ -3397,7 +3442,7 @@ demux_info_print(mpctx->demuxer); //================== Read SUBTITLES (DVD & TEXT) ========================== if(vo_spudec==NULL && mpctx->sh_video && (mpctx->stream->type==STREAMTYPE_DVD || mpctx->stream->type == STREAMTYPE_DVDNAV)){ - init_vo_spudec(); + init_vo_spudec(mpctx); } if(mpctx->sh_video) { @@ -3407,15 +3452,15 @@ if(mpctx->sh_video) { current_module="read_subtitles_file"; if(sub_name){ for (i = 0; sub_name[i] != NULL; ++i) - add_subtitles (sub_name[i], mpctx->sh_video->fps, 0); + add_subtitles(mpctx, sub_name[i], mpctx->sh_video->fps, 0); } if(sub_auto) { // auto load sub file ... char *psub = get_path( "sub/" ); - char **tmp = sub_filenames((psub ? psub : ""), filename); + char **tmp = sub_filenames((psub ? psub : ""), mpctx->filename); int i = 0; free(psub); // release the buffer created by get_path() above while (tmp[i]) { - add_subtitles (tmp[i], mpctx->sh_video->fps, 1); + add_subtitles(mpctx, tmp[i], mpctx->sh_video->fps, 1); free(tmp[i++]); } free(tmp); @@ -3434,20 +3479,20 @@ if (mpctx->global_sub_size) { if (vobsub_index_id >= 0) { // if user asks for a vobsub id, use that first. mpctx->global_sub_pos = mpctx->global_sub_indices[SUB_SOURCE_VOBSUB] + vobsub_index_id; - } else if (dvdsub_id >= 0 && mpctx->global_sub_indices[SUB_SOURCE_DEMUX] >= 0) { + } else if (opts->sub_id >= 0 && mpctx->global_sub_indices[SUB_SOURCE_DEMUX] >= 0) { // if user asks for a dvd sub id, use that next. - mpctx->global_sub_pos = mpctx->global_sub_indices[SUB_SOURCE_DEMUX] + dvdsub_id; + mpctx->global_sub_pos = mpctx->global_sub_indices[SUB_SOURCE_DEMUX] + opts->sub_id; } else if (mpctx->global_sub_indices[SUB_SOURCE_SUBS] >= 0) { // if there are text subs to use, use those. (autosubs come last here) mpctx->global_sub_pos = mpctx->global_sub_indices[SUB_SOURCE_SUBS]; - } else if (dvdsub_id < 0 && mpctx->global_sub_indices[SUB_SOURCE_DEMUX] >= 0) { + } else if (opts->sub_id < 0 && mpctx->global_sub_indices[SUB_SOURCE_DEMUX] >= 0) { // finally select subs by language and container hints - if (dvdsub_id < 0 && dvdsub_lang) - dvdsub_id = demuxer_sub_track_by_lang(mpctx->demuxer, dvdsub_lang); - if (dvdsub_id < 0) - dvdsub_id = demuxer_default_sub_track(mpctx->demuxer); - if (dvdsub_id >= 0) - mpctx->global_sub_pos = mpctx->global_sub_indices[SUB_SOURCE_DEMUX] + dvdsub_id; + if (opts->sub_id < 0 && dvdsub_lang) + opts->sub_id = demuxer_sub_track_by_lang(mpctx->demuxer, dvdsub_lang); + if (opts->sub_id < 0) + opts->sub_id = demuxer_default_sub_track(mpctx->demuxer); + if (opts->sub_id >= 0) + mpctx->global_sub_pos = mpctx->global_sub_indices[SUB_SOURCE_DEMUX] + opts->sub_id; } // rather than duplicate code, use the SUB_SELECT handler to init the right one. mpctx->global_sub_pos--; @@ -3464,7 +3509,7 @@ if (mpctx->global_sub_size) { } mp_msg(MSGT_IDENTIFY,MSGL_INFO,"ID_FILENAME=%s\n", - filename_recode(filename)); + filename_recode(mpctx->filename)); mp_msg(MSGT_IDENTIFY,MSGL_INFO,"ID_DEMUXER=%s\n", mpctx->demuxer->desc->name); if (mpctx->sh_video) { /* Assume FOURCC if all bytes >= 0x20 (' ') */ @@ -3498,14 +3543,14 @@ if (mpctx->global_sub_size) { if(!mpctx->sh_video) goto main; // audio-only -if(!reinit_video_chain()) { +if(!reinit_video_chain(mpctx)) { if(!mpctx->sh_video){ if(!mpctx->sh_audio) goto goto_next_file; goto main; // exit_player(MSGTR_Exit_error); } } - if(vo_flags & 0x08 && vo_spudec) + if(mpctx->sh_video->output_flags & 0x08 && vo_spudec) spudec_set_hw_spu(vo_spudec,mpctx->video_out); #ifdef CONFIG_FREETYPE @@ -3529,7 +3574,6 @@ if(verbose) term_osd = 0; { //int frame_corr_num=0; // //float v_frame=0; // Video -float time_frame=0; // Timer //float num_frames=0; // number of frames played int frame_time_remaining=0; // flag @@ -3539,12 +3583,12 @@ mpctx->num_buffered_frames=0; // Make sure old OSD does not stay around, // e.g. with -fixed-vo and same-resolution files clear_osd_msgs(); -update_osd_msg(); +update_osd_msg(mpctx); //================ SETUP AUDIO ========================== if(mpctx->sh_audio){ - reinit_audio_chain(); + reinit_audio_chain(mpctx); if (mpctx->sh_audio && mpctx->sh_audio->codec) mp_msg(MSGT_IDENTIFY,MSGL_INFO, "ID_AUDIO_CODEC=%s\n", mpctx->sh_audio->codec->name); } @@ -3569,14 +3613,14 @@ if(!mpctx->sh_audio){ mp_msg(MSGT_CPLAYER,MSGL_V,"Freeing %d unused audio chunks.\n",mpctx->d_audio->packs); ds_free_packs(mpctx->d_audio); // free buffered chunks //mpctx->d_audio->id=-2; // do not read audio chunks - //uninit_player(INITIALIZED_AO); // close device + //uninit_player(mpctx, INITIALIZED_AO); // close device } if(!mpctx->sh_video){ mp_msg(MSGT_CPLAYER,MSGL_INFO,MSGTR_Video_NoVideo); mp_msg(MSGT_CPLAYER,MSGL_V,"Freeing %d unused video chunks.\n",mpctx->d_video->packs); ds_free_packs(mpctx->d_video); mpctx->d_video->id=-2; - //if(!fixed_vo) uninit_player(INITIALIZED_VO); + //if(!fixed_vo) uninit_player(mpctx, INITIALIZED_VO); } if (!mpctx->sh_video && !mpctx->sh_audio) @@ -3599,15 +3643,15 @@ if ( use_gui ) { } #endif -mp_input_set_section(NULL); + mp_input_set_section(mpctx->input, NULL); //TODO: add desired (stream-based) sections here -if (mpctx->stream->type==STREAMTYPE_TV) mp_input_set_section("tv"); -if (mpctx->stream->type==STREAMTYPE_DVDNAV) mp_input_set_section("dvdnav"); + if (mpctx->stream->type==STREAMTYPE_TV) mp_input_set_section(mpctx->input, "tv"); + if (mpctx->stream->type==STREAMTYPE_DVDNAV) mp_input_set_section(mpctx->input, "dvdnav"); //==================== START PLAYING ======================= -if(mpctx->loop_times>1) mpctx->loop_times--; else -if(mpctx->loop_times==1) mpctx->loop_times = -1; +if(opts->loop_times>1) opts->loop_times--; else +if(opts->loop_times==1) opts->loop_times = -1; mp_msg(MSGT_CPLAYER,MSGL_INFO,MSGTR_StartPlaying); @@ -3617,7 +3661,7 @@ total_frame_cnt=0; drop_frame_cnt=0; // fix for multifile fps benchmark play_n_frames=play_n_frames_mf; if(play_n_frames==0){ - mpctx->eof=PT_NEXT_ENTRY; goto goto_next_file; + mpctx->stop_play=PT_NEXT_ENTRY; goto goto_next_file; } if (seek_to_sec) { @@ -3638,7 +3682,13 @@ if (mpctx->stream->type == STREAMTYPE_DVDNAV) { } #endif -while(!mpctx->eof){ + get_relative_time(mpctx); // reset current delta + mpctx->time_frame = 0; + mpctx->drop_message_shown = 0; + mpctx->update_video_immediately = true; + mpctx->total_avsync_change = 0; + +while(!mpctx->stop_play){ float aq_sleep_time=0; if(dvd_last_chapter>0) { @@ -3650,16 +3700,16 @@ if(dvd_last_chapter>0) { if(!mpctx->sh_audio && mpctx->d_audio->sh) { mpctx->sh_audio = mpctx->d_audio->sh; mpctx->sh_audio->ds = mpctx->d_audio; - reinit_audio_chain(); + reinit_audio_chain(mpctx); } /*========================== PLAY AUDIO ============================*/ -if (mpctx->sh_audio) - if (!fill_audio_out_buffers()) +if (mpctx->sh_audio && !mpctx->paused) + if (!fill_audio_out_buffers(mpctx)) // at eof, all audio at least written to ao if (!mpctx->sh_video) - mpctx->eof = PT_NEXT_ENTRY; + mpctx->stop_play = AT_END_OF_FILE; if(!mpctx->sh_video) { @@ -3667,15 +3717,14 @@ if(!mpctx->sh_video) { double a_pos=0; // sh_audio can be NULL due to video stream switching // TODO: handle this better - if((!quiet || end_at.type == END_AT_TIME) && mpctx->sh_audio) - a_pos = playing_audio_pts(mpctx->sh_audio, mpctx->d_audio, mpctx->audio_out); + if (mpctx->sh_audio) + a_pos = playing_audio_pts(mpctx); - if(!quiet) - print_status(a_pos, 0, 0); + print_status(mpctx, a_pos, false); if(end_at.type == END_AT_TIME && end_at.pos < a_pos) - mpctx->eof = PT_NEXT_ENTRY; - update_osd_msg(); + mpctx->stop_play = PT_NEXT_ENTRY; + update_osd_msg(mpctx); } else { @@ -3685,18 +3734,31 @@ if(!mpctx->sh_video) { vo_fps=mpctx->sh_video->fps; if (!mpctx->num_buffered_frames) { - double frame_time = update_video(&blit_frame); + double frame_time = update_video(mpctx, &blit_frame); mp_dbg(MSGT_AVSYNC,MSGL_DBG2,"*** ftime=%5.3f ***\n",frame_time); if (mpctx->sh_video->vf_initialized < 0) { mp_msg(MSGT_CPLAYER,MSGL_FATAL, MSGTR_NotInitializeVOPorVO); - mpctx->eof = 1; goto goto_next_file; + mpctx->stop_play = PT_NEXT_ENTRY; + goto goto_next_file; + } + if (blit_frame) { + struct vf_instance *vf = mpctx->sh_video->vfilter; + vf->control(vf, VFCTRL_DRAW_EOSD, NULL); + vf->control(vf, VFCTRL_DRAW_OSD, mpctx->osd); + vo_osd_changed(0); } if (frame_time < 0) - mpctx->eof = 1; + mpctx->stop_play = AT_END_OF_FILE; else { // might return with !eof && !blit_frame if !correct_pts mpctx->num_buffered_frames += blit_frame; - time_frame += frame_time / playback_speed; // for nosound + if (mpctx->update_video_immediately) { + // Show this frame immediately, rest normally + mpctx->update_video_immediately = false; + } else { + mpctx->time_frame += frame_time / opts->playback_speed; + adjust_sync(mpctx, frame_time); + } } } @@ -3710,12 +3772,12 @@ if(!mpctx->sh_video) { #endif current_module="vo_check_events"; - if (vo_config_count) mpctx->video_out->check_events(); + vo_check_events(mpctx->video_out); #ifdef CONFIG_X11 if (stop_xscreensaver) { current_module = "stop_xscreensaver"; - xscreensaver_heartbeat(); + xscreensaver_heartbeat(mpctx->x11_state); } #endif if (heartbeat_cmd) { @@ -3727,7 +3789,7 @@ if(!mpctx->sh_video) { } } - frame_time_remaining = sleep_until_update(&time_frame, &aq_sleep_time); + frame_time_remaining = sleep_until_update(mpctx, &mpctx->time_frame, &aq_sleep_time); //====================== FLIP PAGE (VIDEO BLT): ========================= @@ -3735,14 +3797,15 @@ if(!mpctx->sh_video) { if (!frame_time_remaining && blit_frame) { unsigned int t2=GetTimer(); - if(vo_config_count) mpctx->video_out->flip_page(); + vo_flip_page(mpctx->video_out); mpctx->num_buffered_frames--; - vout_time_usage += (GetTimer() - t2) * 0.000001; + mpctx->last_vo_flip_duration = (GetTimer() - t2) * 0.000001; + vout_time_usage += mpctx->last_vo_flip_duration; + print_status(mpctx, MP_NOPTS_VALUE, true); } -//====================== A-V TIMESTAMP CORRECTION: ========================= - - adjust_sync_and_print_status(frame_time_remaining, time_frame); + else + print_status(mpctx, MP_NOPTS_VALUE, false); //============================ Auto QUALITY ============================ @@ -3764,16 +3827,24 @@ if(auto_quality>0){ set_video_quality(mpctx->sh_video,output_quality); } - if (play_n_frames >= 0 && !frame_time_remaining && blit_frame) { - --play_n_frames; - if (play_n_frames <= 0) mpctx->eof = PT_NEXT_ENTRY; + if (!frame_time_remaining && blit_frame) { + if (play_n_frames >= 0) { + --play_n_frames; + if (play_n_frames <= 0) + mpctx->stop_play = PT_NEXT_ENTRY; + } + if (mpctx->step_frames > 0) { + mpctx->step_frames--; + if (mpctx->step_frames == 0) + pause_player(mpctx); + } } // FIXME: add size based support for -endpos if (end_at.type == END_AT_TIME && !frame_time_remaining && end_at.pos <= mpctx->sh_video->pts) - mpctx->eof = PT_NEXT_ENTRY; + mpctx->stop_play = PT_NEXT_ENTRY; } // end if(mpctx->sh_video) @@ -3794,62 +3865,69 @@ if(auto_quality>0){ } #endif -//============================ Handle PAUSE =============================== - - current_module="pause"; - - if (mpctx->osd_function == OSD_PAUSE) { - mpctx->was_paused = 1; - pause_loop(); - } - -// handle -sstep -if(step_sec>0) { - mpctx->osd_function=OSD_FFW; - rel_seek_secs+=step_sec; -} - - edl_update(mpctx); - //================= Keyboard events, SEEKing ==================== current_module="key_events"; { + while (1) { mp_cmd_t* cmd; - int brk_cmd = 0; - while( !brk_cmd && (cmd = mp_input_get_cmd(0,0,0)) != NULL) { - brk_cmd = run_command(mpctx, cmd); + while ((cmd = mp_input_get_cmd(mpctx->input, 0,0,0)) != NULL) { + run_command(mpctx, cmd); mp_cmd_free(cmd); - if (brk_cmd == 2) - goto goto_enable_cache; + if (mpctx->stop_play) + break; + } + if (!mpctx->paused || mpctx->stop_play || mpctx->rel_seek_secs + || mpctx->abs_seek_pos) + break; + if (mpctx->sh_video) { + update_osd_msg(mpctx); + int hack = vo_osd_changed(0); + vo_osd_changed(hack); + if (hack) + if (redraw_osd(mpctx->sh_video, mpctx->osd) < 0) { + add_step_frame(mpctx); + break; + } + else + vo_osd_changed(0); + } + pause_loop(mpctx); } } - mpctx->was_paused = 0; + +// handle -sstep +if (step_sec > 0 && !mpctx->paused) { + mpctx->osd_function=OSD_FFW; + mpctx->rel_seek_secs+=step_sec; +} + + edl_update(mpctx); /* Looping. */ - if(mpctx->eof==1 && mpctx->loop_times>=0) { - mp_msg(MSGT_CPLAYER,MSGL_V,"loop_times = %d, eof = %d\n", mpctx->loop_times,mpctx->eof); + if(mpctx->stop_play==AT_END_OF_FILE && opts->loop_times>=0) { + mp_msg(MSGT_CPLAYER,MSGL_V,"loop_times = %d\n", opts->loop_times); - if(mpctx->loop_times>1) mpctx->loop_times--; else - if(mpctx->loop_times==1) mpctx->loop_times=-1; + if(opts->loop_times>1) opts->loop_times--; else + if(opts->loop_times==1) opts->loop_times=-1; play_n_frames=play_n_frames_mf; - mpctx->eof=0; - abs_seek_pos=SEEK_ABSOLUTE; rel_seek_secs=seek_to_sec; + mpctx->stop_play=0; + mpctx->abs_seek_pos=SEEK_ABSOLUTE; mpctx->rel_seek_secs=seek_to_sec; loop_seek = 1; } -if(rel_seek_secs || abs_seek_pos){ - if (seek(mpctx, rel_seek_secs, abs_seek_pos) >= 0) { +if(mpctx->rel_seek_secs || mpctx->abs_seek_pos){ + if (seek(mpctx, mpctx->rel_seek_secs, mpctx->abs_seek_pos) >= 0) { // Set OSD: if(!loop_seek){ if( !edl_decision ) - set_osd_bar(0,"Position",0,100,demuxer_get_percent_pos(mpctx->demuxer)); + set_osd_bar(mpctx, 0,"Position",0,100,demuxer_get_percent_pos(mpctx->demuxer)); } } - rel_seek_secs=0; - abs_seek_pos=0; + mpctx->rel_seek_secs=0; + mpctx->abs_seek_pos=0; loop_seek=0; edl_decision = 0; } @@ -3864,7 +3942,7 @@ if(rel_seek_secs || abs_seek_pos){ guiIntfStruct.Position=demuxer_get_percent_pos(mpctx->demuxer); } if ( mpctx->sh_video ) guiIntfStruct.TimeSec=mpctx->sh_video->pts; - else if ( mpctx->sh_audio ) guiIntfStruct.TimeSec=playing_audio_pts(mpctx->sh_audio, mpctx->d_audio, mpctx->audio_out); + else if ( mpctx->sh_audio ) guiIntfStruct.TimeSec=playing_audio_pts(mpctx); guiIntfStruct.LengthInSec=demuxer_get_time_length(mpctx->demuxer); guiGetEvent( guiReDraw,NULL ); guiGetEvent( guiSetVolume,NULL ); @@ -3881,15 +3959,15 @@ if(rel_seek_secs || abs_seek_pos){ } #endif /* CONFIG_GUI */ -} // while(!mpctx->eof) +} // while(!mpctx->stop_play) -mp_msg(MSGT_GLOBAL,MSGL_V,"EOF code: %d \n",mpctx->eof); +mp_msg(MSGT_GLOBAL,MSGL_V,"EOF code: %d \n",mpctx->stop_play); #ifdef CONFIG_DVBIN if(mpctx->dvbin_reopen) { - mpctx->eof = 0; - uninit_player(INITIALIZED_ALL-(INITIALIZED_GUI|INITIALIZED_STREAM|INITIALIZED_INPUT|INITIALIZED_GETCH2|(fixed_vo?INITIALIZED_VO:0))); + mpctx->stop_play = 0; + uninit_player(mpctx, INITIALIZED_ALL-(INITIALIZED_GUI|INITIALIZED_STREAM|INITIALIZED_GETCH2|(opts->fixed_vo?INITIALIZED_VO:0))); cache_uninit(mpctx->stream); mpctx->dvbin_reopen = 0; goto goto_enable_cache; @@ -3927,7 +4005,7 @@ if(benchmark){ } // time to uninit all, except global stuff: -uninit_player(INITIALIZED_ALL-(INITIALIZED_GUI+INITIALIZED_INPUT+(fixed_vo?INITIALIZED_VO:0))); +uninit_player(mpctx, INITIALIZED_ALL-(INITIALIZED_GUI+(opts->fixed_vo?INITIALIZED_VO:0))); if(mpctx->set_of_sub_size > 0) { current_module="sub_free"; @@ -3948,38 +4026,36 @@ if(ass_library) ass_clear_fonts(ass_library); #endif -if(mpctx->eof == PT_NEXT_ENTRY || mpctx->eof == PT_PREV_ENTRY) { - mpctx->eof = mpctx->eof == PT_NEXT_ENTRY ? 1 : -1; - if(play_tree_iter_step(mpctx->playtree_iter,mpctx->play_tree_step,0) == PLAY_TREE_ITER_ENTRY) { - mpctx->eof = 1; - } else { + if (!mpctx->stop_play) // In case some goto jumped here... + mpctx->stop_play = PT_NEXT_ENTRY; + +int playtree_direction = 1; + +if(mpctx->stop_play == PT_NEXT_ENTRY || mpctx->stop_play == PT_PREV_ENTRY) { + if(play_tree_iter_step(mpctx->playtree_iter,mpctx->play_tree_step,0) != PLAY_TREE_ITER_ENTRY) { play_tree_iter_free(mpctx->playtree_iter); mpctx->playtree_iter = NULL; } mpctx->play_tree_step = 1; -} else if(mpctx->eof == PT_UP_NEXT || mpctx->eof == PT_UP_PREV) { - mpctx->eof = mpctx->eof == PT_UP_NEXT ? 1 : -1; +} else if(mpctx->stop_play == PT_UP_NEXT || mpctx->stop_play == PT_UP_PREV) { + int direction = mpctx->stop_play == PT_UP_NEXT ? 1 : -1; if(mpctx->playtree_iter) { - if(play_tree_iter_up_step(mpctx->playtree_iter,mpctx->eof,0) == PLAY_TREE_ITER_ENTRY) { - mpctx->eof = 1; - } else { + if(play_tree_iter_up_step(mpctx->playtree_iter,direction,0) != PLAY_TREE_ITER_ENTRY) { play_tree_iter_free(mpctx->playtree_iter); mpctx->playtree_iter = NULL; } } -} else if (mpctx->eof == PT_STOP) { +} else if (mpctx->stop_play == PT_STOP) { play_tree_iter_free(mpctx->playtree_iter); mpctx->playtree_iter = NULL; } else { // NEXT PREV SRC - mpctx->eof = mpctx->eof == PT_PREV_SRC ? -1 : 1; + playtree_direction = mpctx->stop_play == PT_PREV_SRC ? -1 : 1; } -if(mpctx->eof == 0) mpctx->eof = 1; - while(mpctx->playtree_iter != NULL) { - filename = play_tree_iter_get_file(mpctx->playtree_iter,mpctx->eof); - if(filename == NULL) { - if(play_tree_iter_step(mpctx->playtree_iter,mpctx->eof,0) != PLAY_TREE_ITER_ENTRY) { + mpctx->filename = play_tree_iter_get_file(mpctx->playtree_iter, playtree_direction); + if(mpctx->filename == NULL) { + if(play_tree_iter_step(mpctx->playtree_iter, playtree_direction, 0) != PLAY_TREE_ITER_ENTRY) { play_tree_iter_free(mpctx->playtree_iter); mpctx->playtree_iter = NULL; }; @@ -3997,13 +4073,13 @@ if(use_gui && !mpctx->playtree_iter) { #endif if(use_gui || mpctx->playtree_iter != NULL || player_idle_mode){ - if(!mpctx->playtree_iter) filename = NULL; - mpctx->eof = 0; + if(!mpctx->playtree_iter) mpctx->filename = NULL; + mpctx->stop_play = 0; goto play_next_file; } -exit_player_with_rc(EXIT_EOF, 0); +exit_player_with_rc(mpctx, EXIT_EOF, 0); return 1; } @@ -2,6 +2,8 @@ #ifndef MPLAYER_MPLAYER_H #define MPLAYER_MPLAYER_H +#include "mp_msg.h" + extern char* current_module; extern char * dvd_device; @@ -21,7 +23,6 @@ extern unsigned int osd_visible; extern char * font_name; extern char * sub_font_name; extern float font_factor; -extern float movie_aspect; extern double force_fps; //extern char **sub_name; @@ -29,25 +30,24 @@ extern float sub_delay; extern float sub_fps; extern int sub_auto; -extern char * filename; - extern int stream_cache_size; extern int autosync; -// libmpcodecs: -extern int fullscreen; -extern int flip; - extern int frame_dropping; extern int auto_quality; -extern int audio_id; -extern int video_id; -extern int dvdsub_id; extern int vobsub_id; -void exit_player(const char* how); -void update_set_of_subtitles(void); +static inline void exit_player_bad(const char *how) +{ + if (how) + mp_msg(MSGT_CPLAYER, MSGL_INFO, "Deprecated exit call: %s", how); + exit(1); +} + +struct MPContext; + +void update_set_of_subtitles(struct MPContext *mpctx); #endif /* MPLAYER_MPLAYER_H */ diff --git a/options.h b/options.h new file mode 100644 index 0000000000..a033f2ed9b --- /dev/null +++ b/options.h @@ -0,0 +1,76 @@ +#ifndef MPLAYER_OPTIONS_H +#define MPLAYER_OPTIONS_H + +typedef struct MPOpts { + char **video_driver_list; + char **audio_driver_list; + int fixed_vo; + int vo_ontop; + int screen_size_x; + int screen_size_y; + int vo_screenwidth; + int vo_screenheight; + float force_monitor_aspect; + float monitor_pixel_aspect; + int vidmode; + int fullscreen; + int vo_dbpp; + float vo_panscanrange; + + // ranges -100 - 100, 1000 if the vo default should be used + int vo_gamma_gamma; + int vo_gamma_brightness; + int vo_gamma_contrast; + int vo_gamma_saturation; + int vo_gamma_hue; + + int loop_times; + int correct_pts; + int user_correct_pts; + int key_fifo_size; + int doubleclick_time; + int audio_id; + int video_id; + int sub_id; + float playback_speed; + struct m_obj_settings *vf_settings; + int softzoom; + float movie_aspect; + float screen_size_xy; + int flip; + int vd_use_slices; + struct lavc_param { + int workaround_bugs; + int error_resilience; + int error_concealment; + int gray; + int vstats; + int idct_algo; + int debug; + int vismv; + int skip_top; + int skip_bottom; + int fast; + char *lowres_str; + char *skip_loop_filter_str; + char *skip_idct_str; + char *skip_frame_str; + int threads; + int bitexact; + char *avopt; + } lavc_param; + struct input_conf { + char *config_file; + unsigned int ar_delay; + unsigned int ar_rate; + char *js_dev; + char *ar_dev; + char *in_file; + int use_joystick; + int use_lirc; + int use_lircc; + int use_ar; // apple remote + } input; +} MPOpts; + +#endif diff --git a/osdep/getch2-os2.c b/osdep/getch2-os2.c index ef2dcf22a6..0b6e84683e 100644 --- a/osdep/getch2-os2.c +++ b/osdep/getch2-os2.c @@ -31,6 +31,7 @@ #include "keycodes.h" #include "input/input.h" #include "mp_fifo.h" +#include "getch2.h" #if defined(HAVE_LANGINFO) && defined(CONFIG_ICONV) #include <locale.h> @@ -163,13 +164,13 @@ static int getch2_internal( void ) return -1; } -void getch2( void ) +void getch2(struct mp_fifo *fifo) { int key; key = getch2_internal(); if( key != -1 ) - mplayer_put_key( key ); + mplayer_put_key(fifo, key); } void getch2_enable( void ) diff --git a/osdep/getch2-win.c b/osdep/getch2-win.c index 70608ea366..a1c5601474 100644 --- a/osdep/getch2-win.c +++ b/osdep/getch2-win.c @@ -10,6 +10,8 @@ #include "keycodes.h" #include "input/input.h" #include "mp_fifo.h" +#include "getch2.h" + // HACK, stdin is used as something else below #undef stdin @@ -119,11 +121,11 @@ static int getch2_internal(void) return -1; } -void getch2(void) +void getch2(struct mp_fifo *fifo) { int r = getch2_internal(); if (r >= 0) - mplayer_put_key(r); + mplayer_put_key(fifo, r); } void getch2_enable(void) diff --git a/osdep/getch2.c b/osdep/getch2.c index 65033965bf..403519913a 100644 --- a/osdep/getch2.c +++ b/osdep/getch2.c @@ -37,6 +37,7 @@ #include "mp_fifo.h" #include "keycodes.h" +#include "getch2.h" #ifdef HAVE_TERMIOS static struct termios tio_orig; @@ -95,7 +96,7 @@ int load_termcap(char *termtype){ screen_height=tgetnum("li"); if(screen_width<1 || screen_width>255) screen_width=80; if(screen_height<1 || screen_height>255) screen_height=24; - erase_to_end_of_line= tgetstr("cd",&term_p); + erase_to_end_of_line= tgetstr("ce",&term_p); termcap_add("kP",KEY_PGUP); termcap_add("kN",KEY_PGDWN); @@ -134,7 +135,7 @@ void get_screen_size(void){ #endif } -void getch2(void) +void getch2(struct mp_fifo *fifo) { int retval = read(0, &getch2_buf[getch2_len], BUF_LEN-getch2_len); if (retval < 1) @@ -243,7 +244,7 @@ void getch2(void) getch2_len -= len; for (i = 0; i < getch2_len; i++) getch2_buf[i] = getch2_buf[len+i]; - mplayer_put_key(code); + mplayer_put_key(fifo, code); } } diff --git a/osdep/getch2.h b/osdep/getch2.h index a2206e605d..a85969207c 100644 --- a/osdep/getch2.h +++ b/osdep/getch2.h @@ -22,7 +22,8 @@ void getch2_enable(void); void getch2_disable(void); /* Read a character or a special key code (see keycodes.h) */ -void getch2(void); +struct mp_fifo; +void getch2(struct mp_fifo *fifo); /* slave cmd function for Windows and OS/2 */ int mp_input_slave_cmd_func(int fd,char* dest,int size); diff --git a/osdep/mmap_anon.c b/osdep/mmap_anon.c index f692e2b341..cd42c92b2f 100644 --- a/osdep/mmap_anon.c +++ b/osdep/mmap_anon.c @@ -9,6 +9,8 @@ #include <fcntl.h> #include <sys/mman.h> +#include "mmap_anon.h" + #if defined(MAP_ANON) && !defined(MAP_ANONYMOUS) #define MAP_ANONYMOUS MAP_ANON #endif diff --git a/osdep/shmem.c b/osdep/shmem.c index 378512b38b..1adacfaef5 100644 --- a/osdep/shmem.c +++ b/osdep/shmem.c @@ -35,6 +35,8 @@ #include <sys/shm.h> #endif +#include "shmem.h" + #if defined(MAP_ANONYMOUS) && !defined(MAP_ANON) #define MAP_ANON MAP_ANONYMOUS #endif diff --git a/osdep/timer-darwin.c b/osdep/timer-darwin.c index 4eb973a0c7..64edfe7ef6 100644 --- a/osdep/timer-darwin.c +++ b/osdep/timer-darwin.c @@ -27,10 +27,9 @@ #include "timer.h" /* global variables */ -static double relative_time; static double timebase_ratio; -const char *timer_name = "Darwin accurate"; +const char timer_name[] = "Darwin accurate"; @@ -63,19 +62,6 @@ unsigned int GetTimerMS() return (unsigned int)(uint64_t)(mach_absolute_time() * timebase_ratio * 1e3); } -/* time spent between now and last call in seconds */ -float GetRelativeTime() -{ - double last_time = relative_time; - - if (!relative_time) - InitTimer(); - - relative_time = mach_absolute_time() * timebase_ratio; - - return (float)(relative_time-last_time); -} - /* initialize timer, must be called at least once at start */ void InitTimer() { @@ -84,8 +70,6 @@ void InitTimer() mach_timebase_info(&timebase); timebase_ratio = (double)timebase.numer / (double)timebase.denom * (double)1e-9; - - relative_time = (double)(mach_absolute_time() * timebase_ratio); } #if 0 diff --git a/osdep/timer-linux.c b/osdep/timer-linux.c index cab110927a..6e066711d5 100644 --- a/osdep/timer-linux.c +++ b/osdep/timer-linux.c @@ -8,8 +8,9 @@ #include <time.h> #include <sys/time.h> #include "config.h" +#include "timer.h" -const char *timer_name = +const char timer_name[] = #ifdef HAVE_NANOSLEEP "nanosleep()"; #else @@ -31,45 +32,17 @@ int usec_sleep(int usec_delay) // Returns current time in microseconds unsigned int GetTimer(void){ struct timeval tv; -// float s; gettimeofday(&tv,NULL); -// s=tv.tv_usec;s*=0.000001;s+=tv.tv_sec; return tv.tv_sec * 1000000 + tv.tv_usec; } // Returns current time in milliseconds unsigned int GetTimerMS(void){ struct timeval tv; -// float s; gettimeofday(&tv,NULL); -// s=tv.tv_usec;s*=0.000001;s+=tv.tv_sec; return tv.tv_sec * 1000 + tv.tv_usec / 1000; } -static unsigned int RelativeTime=0; - -// Returns time spent between now and last call in seconds -float GetRelativeTime(void){ -unsigned int t,r; - t=GetTimer(); -// t*=16;printf("time=%ud\n",t); - r=t-RelativeTime; - RelativeTime=t; - return (float)r * 0.000001F; -} - // Initialize timer, must be called at least once at start void InitTimer(void){ - GetRelativeTime(); -} - - -#if 0 -#include <stdio.h> -int main(void){ - float t=0; - InitTimer(); - while(1){ t+=GetRelativeTime();printf("time= %10.6f\r",t);fflush(stdout); } } -#endif - diff --git a/osdep/timer-win2.c b/osdep/timer-win2.c index 8b3685cbd9..3c6b86afa4 100644 --- a/osdep/timer-win2.c +++ b/osdep/timer-win2.c @@ -4,7 +4,7 @@ #include <mmsystem.h> #include "timer.h" -const char *timer_name = "Windows native"; +const char timer_name[] = "Windows native"; // Returns current time in microseconds unsigned int GetTimer(void) @@ -27,18 +27,6 @@ int usec_sleep(int usec_delay){ return 0; } -static DWORD RelativeTime = 0; - -float GetRelativeTime(void) -{ - DWORD t, r; - t = GetTimer(); - r = t - RelativeTime; - RelativeTime = t; - return (float) r *0.000001F; -} - void InitTimer(void) { - GetRelativeTime(); } diff --git a/osdep/timer.h b/osdep/timer.h index 8320665c73..4ddac524ef 100644 --- a/osdep/timer.h +++ b/osdep/timer.h @@ -1,19 +1,12 @@ #ifndef MPLAYER_TIMER_H #define MPLAYER_TIMER_H -extern const char *timer_name; +extern const char timer_name[]; void InitTimer(void); unsigned int GetTimer(void); unsigned int GetTimerMS(void); -//int uGetTimer(); -float GetRelativeTime(void); int usec_sleep(int usec_delay); -/* timer's callback handling */ -typedef void timer_callback( void ); -unsigned set_timer_callback(unsigned ms,timer_callback func); -void restore_timer(void); - #endif /* MPLAYER_TIMER_H */ diff --git a/parser-mpcmd.c b/parser-mpcmd.c index 045ca35613..b0562fb86c 100644 --- a/parser-mpcmd.c +++ b/parser-mpcmd.c @@ -33,7 +33,9 @@ static int mode = 0; // #define UNSET_GLOBAL (mode = GLOBAL) -static int is_entry_option(char *opt, char *param, play_tree_t** ret) { +static int is_entry_option(struct m_config *mconfig, char *opt, char *param, + play_tree_t** ret) +{ play_tree_t* entry = NULL; *ret = NULL; @@ -42,7 +44,7 @@ static int is_entry_option(char *opt, char *param, play_tree_t** ret) { if(!param) return M_OPT_MISSING_PARAM; - entry = parse_playlist_file(param); + entry = parse_playlist_file(mconfig, param); if(!entry) return -1; else { @@ -174,7 +176,7 @@ m_config_parse_mp_command_line(m_config_t *config, int argc, char **argv) const m_option_t* mp_opt = NULL; play_tree_t* entry = NULL; - tmp = is_entry_option(opt,(i+1<argc) ? argv[i + 1] : NULL,&entry); + tmp = is_entry_option(config, opt,(i+1<argc) ? argv[i + 1] : NULL,&entry); if(tmp > 0) { // It's an entry if(entry) { add_entry(&last_parent,&last_entry,entry); diff --git a/playtree.c b/playtree.c index 2318dd1283..1124d2f023 100644 --- a/playtree.c +++ b/playtree.c @@ -408,7 +408,7 @@ play_tree_set_params_from(play_tree_t* dest,play_tree_t* src) { } // all children if deep < 0 -void +static void play_tree_set_flag(play_tree_t* pt, int flags , int deep) { play_tree_t* i; @@ -421,7 +421,7 @@ play_tree_set_flag(play_tree_t* pt, int flags , int deep) { } } -void +static void play_tree_unset_flag(play_tree_t* pt, int flags , int deep) { play_tree_t* i; diff --git a/playtree.h b/playtree.h index 7e454ad1fa..dfd30d6707 100644 --- a/playtree.h +++ b/playtree.h @@ -4,7 +4,7 @@ /// \file /// \ingroup Playtree -struct stream_st; +struct stream; struct m_config; /// \defgroup PlaytreeIterReturn Playtree iterator return code @@ -227,8 +227,9 @@ play_tree_iter_get_file(play_tree_iter_t* iter, int d); /// Create a playtree from a playlist file. /** \ingroup PlaytreeParser */ +struct m_config; play_tree_t* -parse_playtree(struct stream_st *stream, int forced); +parse_playtree(struct stream *stream, struct m_config *mconfig, int forced); /// Clean a tree by destroying all empty elements. play_tree_t* @@ -238,7 +239,7 @@ play_tree_cleanup(play_tree_t* pt); /** \ingroup PlaytreeParser */ play_tree_t* -parse_playlist_file(char* file); +parse_playlist_file(struct m_config *mconfig, char* file); /// \defgroup PtAPI Playtree highlevel API /// \ingroup Playtree diff --git a/playtreeparser.c b/playtreeparser.c index 3a06b0cdab..9d34cc737b 100644 --- a/playtreeparser.c +++ b/playtreeparser.c @@ -20,9 +20,9 @@ #include "libmpdemux/demuxer.h" #include "mp_msg.h" - +struct m_config; extern play_tree_t* -asx_parser_build_tree(char* buffer, int ref); +asx_parser_build_tree(struct m_config *mconfig, char* buffer, int ref); #define BUF_STEP 1024 @@ -199,7 +199,7 @@ parse_asx(play_tree_parser_t* p) { /* NOTHING */; mp_msg(MSGT_PLAYTREE,MSGL_DBG3,"Parsing asx file: [%s]\n",p->buffer); - return asx_parser_build_tree(p->buffer,p->deep); + return asx_parser_build_tree(p->mconfig, p->buffer,p->deep); } static char* @@ -579,7 +579,7 @@ parse_smil(play_tree_parser_t* p) { } static play_tree_t* -embedded_playlist_parse(char *line) { +embedded_playlist_parse(struct m_config *mconfig, char *line) { int f=DEMUXER_TYPE_PLAYLIST; stream_t* stream; play_tree_parser_t* ptp; @@ -595,7 +595,7 @@ embedded_playlist_parse(char *line) { //add new playtree mp_msg(MSGT_PLAYTREE,MSGL_V,"Adding playlist %s to element entryref\n",line); - ptp = play_tree_parser_new(stream,1); + ptp = play_tree_parser_new(stream, mconfig, 1); entry = play_tree_parser_get_play_tree(ptp, 1); play_tree_parser_free(ptp); free_stream(stream); @@ -630,7 +630,7 @@ parse_textplain(play_tree_parser_t* p) { ( ((tolower(c[1]) == 's') && (tolower(c[2])== 'm') && (tolower(c[3]) == 'i')) || ((tolower(c[1]) == 'r') && (tolower(c[2])== 'a') && (tolower(c[3]) == 'm')) ) && (!c[4] || c[4] == '?' || c[4] == '&')) ){ - entry=embedded_playlist_parse(line); + entry=embedded_playlist_parse(p->mconfig, line); embedded = 1; break; } @@ -656,7 +656,7 @@ parse_textplain(play_tree_parser_t* p) { } play_tree_t* -parse_playtree(stream_t *stream, int forced) { +parse_playtree(stream_t *stream, struct m_config *mconfig, int forced) { play_tree_parser_t* p; play_tree_t* ret; @@ -664,7 +664,7 @@ parse_playtree(stream_t *stream, int forced) { assert(stream != NULL); #endif - p = play_tree_parser_new(stream,0); + p = play_tree_parser_new(stream, mconfig, 0); if(!p) return NULL; @@ -731,7 +731,7 @@ void play_tree_add_bpf(play_tree_t* pt, char* filename) } play_tree_t* -parse_playlist_file(char* file) { +parse_playlist_file(struct m_config *mconfig, char* file) { stream_t *stream; play_tree_t* ret; int f=DEMUXER_TYPE_PLAYLIST; @@ -745,7 +745,7 @@ parse_playlist_file(char* file) { mp_msg(MSGT_PLAYTREE,MSGL_V,"Parsing playlist file %s...\n",file); - ret = parse_playtree(stream,1); + ret = parse_playtree(stream, mconfig, 1); free_stream(stream); play_tree_add_bpf(ret, file); @@ -756,13 +756,14 @@ parse_playlist_file(char* file) { play_tree_parser_t* -play_tree_parser_new(stream_t* stream,int deep) { +play_tree_parser_new(stream_t* stream, struct m_config *mconfig, int deep) { play_tree_parser_t* p; p = calloc(1,sizeof(play_tree_parser_t)); if(!p) return NULL; p->stream = stream; + p->mconfig = mconfig; p->deep = deep; p->keep = 1; diff --git a/playtreeparser.h b/playtreeparser.h index f0e11a6970..437d09ad0c 100644 --- a/playtreeparser.h +++ b/playtreeparser.h @@ -12,10 +12,11 @@ /// \file -struct stream_st; +struct stream; typedef struct play_tree_parser { - struct stream_st* stream; + struct stream* stream; + struct m_config *mconfig; char *buffer,*iter,*line; int buffer_size , buffer_end; int deep,keep; @@ -28,7 +29,7 @@ typedef struct play_tree_parser { * \return The new parser. */ play_tree_parser_t* -play_tree_parser_new(struct stream_st* stream,int deep); +play_tree_parser_new(struct stream* stream, struct m_config *mconfig, int deep); /// Destroy a parser. void @@ -88,7 +88,7 @@ typedef struct { unsigned char *scaled_aimage; int auto_palette; /* 1 if we lack a palette and must use an heuristic. */ int font_start_level; /* Darkest value used for the computed font */ - const vo_functions_t *hw_spu; + struct vo *hw_spu; int spu_changed; unsigned int forced_subs_only; /* flag: 0=display all subtitle, !0 display only forced subtitles */ unsigned int is_forced_sub; /* true if current subtitle is a forced subtitle */ @@ -492,7 +492,7 @@ static void spudec_decode(spudec_handle_t *this, int pts100) packet.data = this->packet; packet.size = this->packet_size; packet.timestamp = pts100; - this->hw_spu->draw_frame((uint8_t**)&pkg); + vo_draw_frame(this->hw_spu, (uint8_t**)&pkg); } } @@ -744,8 +744,9 @@ static void scale_image(int x, int y, scale_pixel* table_x, scale_pixel* table_y } } -void sws_spu_image(unsigned char *d1, unsigned char *d2, int dw, int dh, int ds, - unsigned char *s1, unsigned char *s2, int sw, int sh, int ss) +static void sws_spu_image(unsigned char *d1, unsigned char *d2, int dw, int dh, + int ds, unsigned char *s1, unsigned char *s2, int sw, + int sh, int ss) { struct SwsContext *ctx; static SwsFilter filter; @@ -770,7 +771,7 @@ void sws_spu_image(unsigned char *d1, unsigned char *d2, int dw, int dh, int ds, sws_freeContext(ctx); } -void spudec_draw_scaled(void *me, unsigned int dxs, unsigned int dys, void (*draw_alpha)(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride)) +void spudec_draw_scaled(void *me, unsigned int dxs, unsigned int dys, void (*draw_alpha)(void *ctx, int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride), void *ctx) { spudec_handle_t *spu = (spudec_handle_t *)me; scale_pixel *table_x; @@ -787,7 +788,7 @@ void spudec_draw_scaled(void *me, unsigned int dxs, unsigned int dys, void (*dra || (spu->orig_frame_width == dxs && spu->orig_frame_height == dys))) { if (spu->image) { - draw_alpha(spu->start_col, spu->start_row, spu->width, spu->height, + draw_alpha(ctx, spu->start_col, spu->start_row, spu->width, spu->height, spu->image, spu->aimage, spu->stride); spu->spu_changed = 0; } @@ -1088,7 +1089,7 @@ nothing_to_do: spu->scaled_start_row = dys*sub_pos/100 - spu->scaled_height; break; } - draw_alpha(spu->scaled_start_col, spu->scaled_start_row, spu->scaled_width, spu->scaled_height, + draw_alpha(ctx, spu->scaled_start_col, spu->scaled_start_row, spu->scaled_width, spu->scaled_height, spu->scaled_image, spu->scaled_aimage, spu->scaled_stride); spu->spu_changed = 0; } @@ -1107,7 +1108,7 @@ void spudec_update_palette(void * this, unsigned int *palette) if (spu && palette) { memcpy(spu->global_palette, palette, sizeof(spu->global_palette)); if(spu->hw_spu) - spu->hw_spu->control(VOCTRL_SET_SPU_PALETTE,spu->global_palette); + vo_control(spu->hw_spu, VOCTRL_SET_SPU_PALETTE, spu->global_palette); } } @@ -1211,11 +1212,11 @@ void spudec_free(void *this) } } -void spudec_set_hw_spu(void *this, const vo_functions_t *hw_spu) +void spudec_set_hw_spu(void *this, struct vo *hw_spu) { spudec_handle_t *spu = (spudec_handle_t*)this; if (!spu) return; spu->hw_spu = hw_spu; - hw_spu->control(VOCTRL_SET_SPU_PALETTE,spu->global_palette); + vo_control(hw_spu, VOCTRL_SET_SPU_PALETTE, spu->global_palette); } @@ -6,7 +6,7 @@ void spudec_heartbeat(void *this, unsigned int pts100); void spudec_assemble(void *this, unsigned char *packet, unsigned int len, int pts100); void spudec_draw(void *this, void (*draw_alpha)(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride)); -void spudec_draw_scaled(void *this, unsigned int dxs, unsigned int dys, void (*draw_alpha)(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride)); +void spudec_draw_scaled(void *this, unsigned int dxs, unsigned int dys, void (*draw_alpha)(void *ctx, int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride), void *ctx); void spudec_update_palette(void *this, unsigned int *palette); void *spudec_new_scaled(unsigned int *palette, unsigned int frame_width, unsigned int frame_height, uint8_t *extradata, int extradata_len); void *spudec_new(unsigned int *palette); @@ -14,7 +14,7 @@ void spudec_free(void *this); void spudec_reset(void *this); // called after seek int spudec_visible(void *this); // check if spu is visible void spudec_set_font_factor(void * this, double factor); // sets the equivalent to ffactor -void spudec_set_hw_spu(void *this, const vo_functions_t *hw_spu); +void spudec_set_hw_spu(void *this, struct vo *hw_spu); int spudec_changed(void *this); void spudec_calc_bbox(void *me, unsigned int dxs, unsigned int dys, unsigned int* bbox); void spudec_set_forced_subs_only(void * const this, const unsigned int flag); diff --git a/stream/asf_mmst_streaming.c b/stream/asf_mmst_streaming.c index c05ecb9240..f19ffe50a7 100644 --- a/stream/asf_mmst_streaming.c +++ b/stream/asf_mmst_streaming.c @@ -35,7 +35,7 @@ #include <inttypes.h> #include "config.h" - +#include "options.h" #include "mp_msg.h" #include "help_mp.h" @@ -646,6 +646,7 @@ int asf_mmst_streaming_start(stream_t *stream) memset (data, 0, 40); + int audio_id = stream->opts->audio_id; if (audio_id > 0) { data[2] = 0xFF; data[3] = 0xFF; diff --git a/stream/asf_streaming.c b/stream/asf_streaming.c index 64a8152ee3..73cff872b5 100644 --- a/stream/asf_streaming.c +++ b/stream/asf_streaming.c @@ -8,6 +8,7 @@ #include "config.h" #include "mp_msg.h" #include "help_mp.h" +#include "options.h" #if HAVE_WINSOCK2_H #include <winsock2.h> @@ -144,9 +145,6 @@ printf("0x%02X\n", stream_chunck->type ); return stream_chunck->size+4; } -extern int audio_id; -extern int video_id; - static void close_s(stream_t *stream) { close(stream->fd); stream->fd=-1; @@ -362,24 +360,24 @@ static int asf_streaming_parse_header(int fd, streaming_ctrl_t* streaming_ctrl) return -1; } - if (audio_id > 0) + if (*streaming_ctrl->audio_id_ptr > 0) // a audio stream was forced - asf_ctrl->audio_id = audio_id; + asf_ctrl->audio_id = *streaming_ctrl->audio_id_ptr; else if (a_idx >= 0) asf_ctrl->audio_id = asf_ctrl->audio_streams[a_idx]; else if (asf_ctrl->n_audio) { mp_msg(MSGT_NETWORK, MSGL_WARN, MSGTR_MPDEMUX_ASF_Bandwidth2SmallDeselectedAudio); - audio_id = -2; + *streaming_ctrl->audio_id_ptr = -2; } - if (video_id > 0) + if (*streaming_ctrl->video_id_ptr > 0) // a video stream was forced - asf_ctrl->video_id = video_id; + asf_ctrl->video_id = *streaming_ctrl->video_id_ptr; else if (v_idx >= 0) asf_ctrl->video_id = asf_ctrl->video_streams[v_idx]; else if (asf_ctrl->n_video) { mp_msg(MSGT_NETWORK, MSGL_WARN, MSGTR_MPDEMUX_ASF_Bandwidth2SmallDeselectedVideo); - video_id = -2; + *streaming_ctrl->video_id_ptr = -2; } return 1; @@ -815,6 +813,8 @@ static int open_s(stream_t *stream,int mode, void* opts, int* file_format) { if( stream->streaming_ctrl==NULL ) { return STREAM_ERROR; } + stream->streaming_ctrl->audio_id_ptr = &stream->opts->audio_id; + stream->streaming_ctrl->video_id_ptr = &stream->opts->video_id; stream->streaming_ctrl->bandwidth = network_bandwidth; url = url_new(stream->url); stream->streaming_ctrl->url = check4proxies(url); diff --git a/stream/cache2.c b/stream/cache2.c index d211ba483b..c9d5539035 100644 --- a/stream/cache2.c +++ b/stream/cache2.c @@ -39,9 +39,6 @@ static void *ThreadProc(void *s); #include "cache2.h" extern int use_gui; -int stream_fill_buffer(stream_t *s); -int stream_seek_long(stream_t *s,off_t pos); - typedef struct { // constats: unsigned char *buffer; // base pointer of the alllocated buffer memory @@ -74,13 +71,13 @@ static int min_fill=0; int cache_fill_status=0; -void cache_stats(cache_vars_t* s){ +static void cache_stats(cache_vars_t* s){ int newb=s->max_filepos-s->read_filepos; // new bytes in the buffer mp_msg(MSGT_CACHE,MSGL_INFO,"0x%06X [0x%06X] 0x%06X ",(int)s->min_filepos,(int)s->read_filepos,(int)s->max_filepos); mp_msg(MSGT_CACHE,MSGL_INFO,"%3d %% (%3d%%)\n",100*newb/s->buffer_size,100*min_fill/s->buffer_size); } -int cache_read(cache_vars_t* s,unsigned char* buf,int size){ +static int cache_read(cache_vars_t* s,unsigned char* buf,int size){ int total=0; while(size>0){ int pos,newb,len; @@ -126,7 +123,7 @@ int cache_read(cache_vars_t* s,unsigned char* buf,int size){ return total; } -int cache_fill(cache_vars_t* s){ +static int cache_fill(cache_vars_t* s){ int back,back2,newb,space,len,pos; off_t read=s->read_filepos; @@ -246,7 +243,7 @@ static int cache_execute_control(cache_vars_t *s) { return res; } -cache_vars_t* cache_init(int size,int sector){ +static cache_vars_t* cache_init(int size,int sector){ int num; #if !defined(__MINGW32__) && !defined(PTHREAD_CACHE) && !defined(__OS2__) cache_vars_t* s=shmem_alloc(sizeof(cache_vars_t)); diff --git a/stream/network.h b/stream/network.h index bc4ec598ef..c00bffd5e5 100644 --- a/stream/network.h +++ b/stream/network.h @@ -53,6 +53,9 @@ typedef struct streaming_control { int (*streaming_read)( int fd, char *buffer, int buffer_size, struct streaming_control *stream_ctrl ); int (*streaming_seek)( int fd, off_t pos, struct streaming_control *stream_ctrl ); void *data; + // hacks for asf + int *audio_id_ptr; + int *video_id_ptr; } streaming_ctrl_t; //int streaming_start( stream_t *stream, int *demuxer_type, URL_t *url ); diff --git a/stream/open.c b/stream/open.c index 0ec0222c32..dad7c49db7 100644 --- a/stream/open.c +++ b/stream/open.c @@ -30,7 +30,8 @@ int dvd_title=0; // Open a new stream (stdin/file/vcd/url) -stream_t* open_stream(char* filename,char** options, int* file_format){ +stream_t* open_stream(char* filename, struct MPOpts *options, int* file_format) +{ // Check if playlist or unknown if (*file_format != DEMUXER_TYPE_PLAYLIST){ *file_format=DEMUXER_TYPE_UNKNOWN; diff --git a/stream/stream.c b/stream/stream.c index 85b0a1f907..7688006896 100644 --- a/stream/stream.c +++ b/stream/stream.c @@ -32,7 +32,9 @@ //#include "vcd_read_bincue.h" -static int (*stream_check_interrupt_cb)(int time) = NULL; +struct input_ctx; +static int (*stream_check_interrupt_cb)(struct input_ctx *ctx, int time); +static struct input_ctx *stream_check_interrupt_ctx; extern const stream_info_t stream_info_vcd; extern const stream_info_t stream_info_cdda; @@ -119,9 +121,11 @@ static const stream_info_t* const auto_open_streams[] = { NULL }; -stream_t* open_stream_plugin(const stream_info_t* sinfo,char* filename,int mode, - char** options, int* file_format, int* ret, - char** redirected_url) { +static stream_t *open_stream_plugin(const stream_info_t *sinfo, char *filename, + int mode, struct MPOpts *options, + int *file_format, int *ret, + char **redirected_url) +{ void* arg = NULL; stream_t* s; m_struct_t* desc = (m_struct_t*)sinfo->opts; @@ -138,18 +142,9 @@ stream_t* open_stream_plugin(const stream_info_t* sinfo,char* filename,int mode, return NULL; } } - if(options) { - int i; - for(i = 0 ; options[i] != NULL ; i += 2) { - mp_msg(MSGT_OPEN,MSGL_DBG2, "Set stream arg %s=%s\n", - options[i],options[i+1]); - if(!m_struct_set(desc,arg,options[i],options[i+1])) - mp_msg(MSGT_OPEN,MSGL_WARN, "Failed to set stream option %s=%s\n", - options[i],options[i+1]); - } - } } s = new_stream(-2,-2); + s->opts = options; s->url=strdup(filename); s->flags |= mode; *ret = sinfo->open(s,mode,arg,file_format); @@ -186,7 +181,9 @@ stream_t* open_stream_plugin(const stream_info_t* sinfo,char* filename,int mode, } -stream_t* open_stream_full(char* filename,int mode, char** options, int* file_format) { +stream_t *open_stream_full(char *filename,int mode, struct MPOpts *options, + int* file_format) +{ int i,j,l,r; const stream_info_t* sinfo; stream_t* s; @@ -228,7 +225,8 @@ stream_t* open_stream_full(char* filename,int mode, char** options, int* file_fo return NULL; } -stream_t* open_output_stream(char* filename,char** options) { +stream_t *open_output_stream(char *filename, struct MPOpts *options) +{ int file_format; //unused if(!filename) { mp_msg(MSGT_OPEN,MSGL_ERR,"open_output_stream(), NULL filename, report this bug\n"); @@ -460,11 +458,14 @@ stream_t* new_ds_stream(demux_stream_t *ds) { return s; } -void stream_set_interrupt_callback(int (*cb)(int)) { +void stream_set_interrupt_callback(int (*cb)(struct input_ctx *, int), + struct input_ctx *ctx) +{ stream_check_interrupt_cb = cb; + stream_check_interrupt_ctx = ctx; } int stream_check_interrupt(int time) { if(!stream_check_interrupt_cb) return 0; - return stream_check_interrupt_cb(time); + return stream_check_interrupt_cb(stream_check_interrupt_ctx, time); } diff --git a/stream/stream.h b/stream/stream.h index 686288071f..87cda3637a 100644 --- a/stream/stream.h +++ b/stream/stream.h @@ -70,7 +70,7 @@ #include "network.h" #endif -struct stream_st; +struct stream; typedef struct stream_info_st { const char *info; const char *name; @@ -79,7 +79,7 @@ typedef struct stream_info_st { /// mode isn't used atm (ie always READ) but it shouldn't be ignored /// opts is at least in it's defaults settings and may have been /// altered by url parsing if enabled and the options string parsing. - int (*open)(struct stream_st* st, int mode, void* opts, int* file_format); + int (*open)(struct stream* st, int mode, void* opts, int* file_format); const char* protocols[MAX_STREAM_PROTOCOLS]; const void* opts; int opts_url; /* If this is 1 we will parse the url as an option string @@ -87,19 +87,19 @@ typedef struct stream_info_st { * options string given to open_stream_plugin */ } stream_info_t; -typedef struct stream_st { +typedef struct stream { // Read - int (*fill_buffer)(struct stream_st *s, char* buffer, int max_len); + int (*fill_buffer)(struct stream *s, char* buffer, int max_len); // Write - int (*write_buffer)(struct stream_st *s, char* buffer, int len); + int (*write_buffer)(struct stream *s, char* buffer, int len); // Seek - int (*seek)(struct stream_st *s,off_t pos); + int (*seek)(struct stream *s,off_t pos); // Control // Will be later used to let streams like dvd and cdda report // their structure (ie tracks, chapters, etc) - int (*control)(struct stream_st *s,int cmd,void* arg); + int (*control)(struct stream *s,int cmd,void* arg); // Close - void (*close)(struct stream_st *s); + void (*close)(struct stream *s); int fd; // file descriptor, see man open(2) int type; // see STREAMTYPE_* @@ -113,20 +113,21 @@ typedef struct stream_st { void* cache_data; void* priv; // used for DVD, TV, RTSP etc char* url; // strdup() of filename/url + struct MPOpts *opts; #ifdef CONFIG_NETWORK streaming_ctrl_t *streaming_ctrl; #endif unsigned char buffer[STREAM_BUFFER_SIZE>VCD_SECTOR_SIZE?STREAM_BUFFER_SIZE:VCD_SECTOR_SIZE]; } stream_t; +int stream_fill_buffer(stream_t *s); +int stream_seek_long(stream_t *s,off_t pos); #ifdef CONFIG_STREAM_CACHE int stream_enable_cache(stream_t *stream,int size,int min,int prefill); int cache_stream_fill_buffer(stream_t *s); int cache_stream_seek_long(stream_t *s,off_t pos); #else // no cache, define wrappers: -int stream_fill_buffer(stream_t *s); -int stream_seek_long(stream_t *s,off_t pos); #define cache_stream_fill_buffer(x) stream_fill_buffer(x) #define cache_stream_seek_long(x,y) stream_seek_long(x,y) #define stream_enable_cache(x,y,z,w) 1 @@ -289,17 +290,20 @@ inline static int stream_skip(stream_t *s,off_t len){ return 1; } +struct MPOpts; void stream_reset(stream_t *s); int stream_control(stream_t *s, int cmd, void *arg); stream_t* new_stream(int fd,int type); void free_stream(stream_t *s); stream_t* new_memory_stream(unsigned char* data,int len); -stream_t* open_stream(char* filename,char** options,int* file_format); -stream_t* open_stream_full(char* filename,int mode, char** options, int* file_format); -stream_t* open_output_stream(char* filename,char** options); +stream_t* open_stream(char* filename, struct MPOpts *options,int* file_format); +stream_t* open_stream_full(char* filename,int mode, struct MPOpts *options, int* file_format); +stream_t* open_output_stream(char* filename,struct MPOpts *options); /// Set the callback to be used by libstream to check for user /// interruption during long blocking operations (cache filling, etc). -void stream_set_interrupt_callback(int (*cb)(int)); +struct input_ctx; +void stream_set_interrupt_callback(int (*cb)(struct input_ctx*, int), + struct input_ctx *ctx); /// Call the interrupt checking callback if there is one. int stream_check_interrupt(int time); diff --git a/stream/stream_dvd.c b/stream/stream_dvd.c index ae07239ad5..05f9c411ab 100644 --- a/stream/stream_dvd.c +++ b/stream/stream_dvd.c @@ -324,7 +324,7 @@ static int dvd_next_cell(dvd_priv_t *d) { return next_cell; } -int dvd_read_sector(dvd_priv_t *d,unsigned char* data) { +static int dvd_read_sector(dvd_priv_t *d,unsigned char* data) { int len; if(d->packs_left==0) { @@ -444,7 +444,7 @@ read_next: return d->cur_pack-1; } -void dvd_seek(dvd_priv_t *d,int pos) { +static void dvd_seek(dvd_priv_t *d,int pos) { d->packs_left=-1; d->cur_pack=pos; @@ -482,7 +482,7 @@ void dvd_seek(dvd_priv_t *d,int pos) { d->angle_seek=1; } -void dvd_close(dvd_priv_t *d) { +static void dvd_close(dvd_priv_t *d) { ifoClose(d->vts_file); ifoClose(d->vmg_file); DVDCloseFile(d->title); diff --git a/stream/stream_netstream.c b/stream/stream_netstream.c index 734c1f6412..593e60bd97 100644 --- a/stream/stream_netstream.c +++ b/stream/stream_netstream.c @@ -201,7 +201,7 @@ static int seek(stream_t *s,off_t newpos) { return 1; } -static int net_stream_reset(struct stream_st *s) { +static int net_stream_reset(struct stream *s) { mp_net_stream_packet_t* pack; pack = send_net_stream_cmd(s,NET_STREAM_RESET,NULL,0); @@ -212,7 +212,7 @@ static int net_stream_reset(struct stream_st *s) { return 1; } -static int control(struct stream_st *s,int cmd,void* arg) { +static int control(struct stream *s,int cmd,void* arg) { switch(cmd) { case STREAM_CTRL_RESET: return net_stream_reset(s); @@ -220,7 +220,7 @@ static int control(struct stream_st *s,int cmd,void* arg) { return STREAM_UNSUPPORTED; } -static void close_s(struct stream_st *s) { +static void close_s(struct stream *s) { mp_net_stream_packet_t* pack; pack = send_net_stream_cmd(s,NET_STREAM_CLOSE,NULL,0); diff --git a/stream/stream_radio.c b/stream/stream_radio.c index 9792fb142c..f0b9745a5f 100644 --- a/stream/stream_radio.c +++ b/stream/stream_radio.c @@ -155,7 +155,7 @@ static const struct m_struct_st stream_opts = { stream_opts_fields }; -static void close_s(struct stream_st * stream); +static void close_s(struct stream *stream); #ifdef CONFIG_RADIO_CAPTURE static int clear_buffer(radio_priv_t* priv); #endif @@ -900,7 +900,7 @@ static int init_audio(radio_priv_t *priv) * \parameter frequency pointer to float, which will contain frequency in MHz * \return 1 if success,0 - otherwise */ -int radio_get_freq(struct stream_st *stream, float* frequency){ +int radio_get_freq(struct stream *stream, float *frequency){ radio_priv_t* priv=(radio_priv_t*)stream->priv; if (!frequency) @@ -915,7 +915,7 @@ int radio_get_freq(struct stream_st *stream, float* frequency){ * \parameter frequency frequency in MHz * \return 1 if success,0 - otherwise */ -int radio_set_freq(struct stream_st *stream, float frequency){ +int radio_set_freq(struct stream *stream, float frequency){ radio_priv_t* priv=(radio_priv_t*)stream->priv; if (set_frequency(priv,frequency)!=STREAM_OK){ @@ -934,7 +934,7 @@ int radio_set_freq(struct stream_st *stream, float frequency){ * \return 1 if success,0 - otherwise * */ -int radio_step_freq(struct stream_st *stream, float step_interval){ +int radio_step_freq(struct stream *stream, float step_interval){ float frequency; radio_priv_t* priv=(radio_priv_t*)stream->priv; @@ -957,7 +957,7 @@ int radio_step_freq(struct stream_st *stream, float step_interval){ * if channel parameter is NULL function prints error message and does nothing, otherwise * changes channel to prev or next in list */ -int radio_step_channel(struct stream_st *stream, int direction) { +int radio_step_channel(struct stream *stream, int direction) { radio_priv_t* priv=(radio_priv_t*)stream->priv; if (priv->radio_channel_list) { @@ -999,7 +999,7 @@ int radio_step_channel(struct stream_st *stream, int direction) { * if channel parameter is NULL function prints error message and does nothing, otherwise * changes channel to given */ -int radio_set_channel(struct stream_st *stream, char *channel) { +int radio_set_channel(struct stream *stream, char *channel) { radio_priv_t* priv=(radio_priv_t*)stream->priv; int i, channel_int; radio_channels_t* tmp; @@ -1047,7 +1047,7 @@ int radio_set_channel(struct stream_st *stream, char *channel) { * * NOTE: return value may be NULL (e.g. when channel list not initialized) */ -char* radio_get_channel_name(struct stream_st *stream){ +char* radio_get_channel_name(struct stream *stream){ radio_priv_t* priv=(radio_priv_t*)stream->priv; if (priv->radio_channel_current) { return priv->radio_channel_current->name; @@ -1059,7 +1059,7 @@ char* radio_get_channel_name(struct stream_st *stream){ * \brief fills given buffer with audio data * \return number of bytes, written into buffer */ -static int fill_buffer_s(struct stream_st *s, char* buffer, int max_len){ +static int fill_buffer_s(struct stream *s, char *buffer, int max_len){ int len=max_len; #ifdef CONFIG_RADIO_CAPTURE @@ -1220,7 +1220,7 @@ static int open_s(stream_t *stream,int mode, void* opts, int* file_format) { /***************************************************************** * Close stream. Clear structures. */ -static void close_s(struct stream_st * stream){ +static void close_s(struct stream *stream){ radio_priv_t* priv=(radio_priv_t*)stream->priv; radio_channels_t * tmp; if (!priv) return; diff --git a/stream/stream_radio.h b/stream/stream_radio.h index e77f4aa05e..69066970e3 100644 --- a/stream/stream_radio.h +++ b/stream/stream_radio.h @@ -36,11 +36,11 @@ typedef struct radio_param_s{ extern radio_param_t stream_radio_defaults; -int radio_set_freq(struct stream_st *stream, float freq); -int radio_get_freq(struct stream_st *stream, float* freq); -char* radio_get_channel_name(struct stream_st *stream); -int radio_set_channel(struct stream_st *stream, char *channel); -int radio_step_channel(struct stream_st *stream, int direction); -int radio_step_freq(struct stream_st *stream, float step_interval); +int radio_set_freq(struct stream *stream, float freq); +int radio_get_freq(struct stream *stream, float* freq); +char* radio_get_channel_name(struct stream *stream); +int radio_set_channel(struct stream *stream, char *channel); +int radio_step_channel(struct stream *stream, int direction); +int radio_step_freq(struct stream *stream, float step_interval); #endif /* MPLAYER_STREAM_RADIO_H */ diff --git a/stream/stream_rtsp.c b/stream/stream_rtsp.c index 591fc1765a..94599c2b4a 100644 --- a/stream/stream_rtsp.c +++ b/stream/stream_rtsp.c @@ -130,7 +130,7 @@ rtsp_streaming_start (stream_t *stream) } static void -rtsp_streaming_close (struct stream_st *s) +rtsp_streaming_close (struct stream *s) { rtsp_session_t *rtsp = NULL; diff --git a/stream/stream_vstream.c b/stream/stream_vstream.c index 4d0d972ebf..adc8d89d1d 100644 --- a/stream/stream_vstream.c +++ b/stream/stream_vstream.c @@ -95,11 +95,11 @@ static int seek(stream_t *s,off_t newpos) { return 1; } -static int control(struct stream_st *s,int cmd,void* arg) { +static int control(struct stream *s,int cmd,void *arg) { return STREAM_UNSUPPORTED; } -static void close_s(struct stream_st *s) { +static void close_s(struct stream *s) { } static int open_s(stream_t *stream, int mode, void* opts, int* file_format) { diff --git a/stream/tv.c b/stream/tv.c index 58321d5302..641737a9f1 100644 --- a/stream/tv.c +++ b/stream/tv.c @@ -337,7 +337,7 @@ int tv_set_norm(tvi_handle_t *tvh, char* norm) return 1; } -int tv_set_norm_i(tvi_handle_t *tvh, int norm) +static int tv_set_norm_i(tvi_handle_t *tvh, int norm) { tvh->norm = norm; diff --git a/subreader.c b/subreader.c index 72e050380f..ddaeceef8e 100644 --- a/subreader.c +++ b/subreader.c @@ -1150,7 +1150,7 @@ subtitle* subcp_recode (subtitle *sub) #ifndef max #define max(a,b) (((a)>(b))?(a):(b)) #endif -subtitle* sub_fribidi (subtitle *sub, int sub_utf8) +static subtitle* sub_fribidi (subtitle *sub, int sub_utf8) { FriBidiChar logical[LINE_LEN+1], visual[LINE_LEN+1]; // Hopefully these two won't smash the stack char *ip = NULL, *op = NULL; diff --git a/subreader.h b/subreader.h index 79fd0da0cb..b29551e3f9 100644 --- a/subreader.h +++ b/subreader.h @@ -68,12 +68,12 @@ sub_data* sub_read_file (char *filename, float pts); subtitle* subcp_recode (subtitle *sub); // enca_fd is the file enca uses to determine the codepage. // setting to NULL disables enca. -struct stream_st; -void subcp_open (struct stream_st *st); /* for demux_ogg.c */ +struct stream; +void subcp_open (struct stream *st); /* for demux_ogg.c */ void subcp_close (void); /* for demux_ogg.c */ #ifdef CONFIG_ENCA const char* guess_buffer_cp(unsigned char* buffer, int buflen, const char *preferred_language, const char *fallback); -const char* guess_cp(struct stream_st *st, const char *preferred_language, const char *fallback); +const char* guess_cp(struct stream *st, const char *preferred_language, const char *fallback); #endif char ** sub_filenames(const char *path, char *fname); void list_sub_file(sub_data* subd); diff --git a/talloc.c b/talloc.c new file mode 100644 index 0000000000..63550cf4d4 --- /dev/null +++ b/talloc.c @@ -0,0 +1,1758 @@ +/* + Samba Unix SMB/CIFS implementation. + + Samba trivial allocation library - new interface + + NOTE: Please read talloc_guide.txt for full documentation + + Copyright (C) Andrew Tridgell 2004 + Copyright (C) Stefan Metzmacher 2006 + + ** NOTE! The following LGPL license applies to the talloc + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see <http://www.gnu.org/licenses/>. +*/ + +/* + inspired by http://swapped.cc/halloc/ +*/ + +// Hardcode these for MPlayer assuming a working system. +// Original used autoconf detection with workarounds for broken systems. +#define HAVE_VA_COPY +#include <stdio.h> +#include <stdlib.h> +#include <stdarg.h> +#include <stdint.h> +#include <string.h> +#include <stdbool.h> +#define MIN(a,b) ((a)<(b)?(a):(b)) +#define strnlen rep_strnlen +static size_t rep_strnlen(const char *s, size_t max) +{ + size_t len; + + for (len = 0; len < max; len++) { + if (s[len] == '\0') { + break; + } + } + return len; +} + + + +#ifdef _SAMBA_BUILD_ +#include "version.h" +#if (SAMBA_VERSION_MAJOR<4) +#include "includes.h" +/* This is to circumvent SAMBA3's paranoid malloc checker. Here in this file + * we trust ourselves... */ +#ifdef malloc +#undef malloc +#endif +#ifdef realloc +#undef realloc +#endif +#define _TALLOC_SAMBA3 +#endif /* (SAMBA_VERSION_MAJOR<4) */ +#endif /* _SAMBA_BUILD_ */ + +#ifndef _TALLOC_SAMBA3 +// Workarounds for missing standard features, not used in MPlayer +// #include "replace.h" +#include "talloc.h" +#endif /* not _TALLOC_SAMBA3 */ + +/* use this to force every realloc to change the pointer, to stress test + code that might not cope */ +#define ALWAYS_REALLOC 0 + + +#define MAX_TALLOC_SIZE 0x10000000 +#define TALLOC_MAGIC 0xe814ec70 +#define TALLOC_FLAG_FREE 0x01 +#define TALLOC_FLAG_LOOP 0x02 +#define TALLOC_FLAG_POOL 0x04 /* This is a talloc pool */ +#define TALLOC_FLAG_POOLMEM 0x08 /* This is allocated in a pool */ +#define TALLOC_MAGIC_REFERENCE ((const char *)1) + +/* by default we abort when given a bad pointer (such as when talloc_free() is called + on a pointer that came from malloc() */ +#ifndef TALLOC_ABORT +#define TALLOC_ABORT(reason) abort() +#endif + +#ifndef discard_const_p +#if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T) +# define discard_const_p(type, ptr) ((type *)((intptr_t)(ptr))) +#else +# define discard_const_p(type, ptr) ((type *)(ptr)) +#endif +#endif + +/* these macros gain us a few percent of speed on gcc */ +#if (__GNUC__ >= 3) +/* the strange !! is to ensure that __builtin_expect() takes either 0 or 1 + as its first argument */ +#ifndef likely +#define likely(x) __builtin_expect(!!(x), 1) +#endif +#ifndef unlikely +#define unlikely(x) __builtin_expect(!!(x), 0) +#endif +#else +#ifndef likely +#define likely(x) (x) +#endif +#ifndef unlikely +#define unlikely(x) (x) +#endif +#endif + +/* this null_context is only used if talloc_enable_leak_report() or + talloc_enable_leak_report_full() is called, otherwise it remains + NULL +*/ +static void *null_context; +static void *autofree_context; + +struct talloc_reference_handle { + struct talloc_reference_handle *next, *prev; + void *ptr; +}; + +typedef int (*talloc_destructor_t)(void *); + +struct talloc_chunk { + struct talloc_chunk *next, *prev; + struct talloc_chunk *parent, *child; + struct talloc_reference_handle *refs; + talloc_destructor_t destructor; + const char *name; + size_t size; + unsigned flags; + + /* + * "pool" has dual use: + * + * For the talloc pool itself (i.e. TALLOC_FLAG_POOL is set), "pool" + * marks the end of the currently allocated area. + * + * For members of the pool (i.e. TALLOC_FLAG_POOLMEM is set), "pool" + * is a pointer to the struct talloc_chunk of the pool that it was + * allocated from. This way children can quickly find the pool to chew + * from. + */ + void *pool; +}; + +/* 16 byte alignment seems to keep everyone happy */ +#define TC_HDR_SIZE ((sizeof(struct talloc_chunk)+15)&~15) +#define TC_PTR_FROM_CHUNK(tc) ((void *)(TC_HDR_SIZE + (char*)tc)) + +static void talloc_abort_double_free(void) +{ + TALLOC_ABORT("Bad talloc magic value - double free"); +} + +static void talloc_abort_unknown_value(void) +{ + TALLOC_ABORT("Bad talloc magic value - unknown value"); +} + +/* panic if we get a bad magic value */ +static inline struct talloc_chunk *talloc_chunk_from_ptr(const void *ptr) +{ + const char *pp = (const char *)ptr; + struct talloc_chunk *tc = discard_const_p(struct talloc_chunk, pp - TC_HDR_SIZE); + if (unlikely((tc->flags & (TALLOC_FLAG_FREE | ~0xF)) != TALLOC_MAGIC)) { + if (tc->flags & TALLOC_FLAG_FREE) { + talloc_abort_double_free(); + } else { + talloc_abort_unknown_value(); + } + } + return tc; +} + +/* hook into the front of the list */ +#define _TLIST_ADD(list, p) \ +do { \ + if (!(list)) { \ + (list) = (p); \ + (p)->next = (p)->prev = NULL; \ + } else { \ + (list)->prev = (p); \ + (p)->next = (list); \ + (p)->prev = NULL; \ + (list) = (p); \ + }\ +} while (0) + +/* remove an element from a list - element doesn't have to be in list. */ +#define _TLIST_REMOVE(list, p) \ +do { \ + if ((p) == (list)) { \ + (list) = (p)->next; \ + if (list) (list)->prev = NULL; \ + } else { \ + if ((p)->prev) (p)->prev->next = (p)->next; \ + if ((p)->next) (p)->next->prev = (p)->prev; \ + } \ + if ((p) && ((p) != (list))) (p)->next = (p)->prev = NULL; \ +} while (0) + + +/* + return the parent chunk of a pointer +*/ +static inline struct talloc_chunk *talloc_parent_chunk(const void *ptr) +{ + struct talloc_chunk *tc; + + if (unlikely(ptr == NULL)) { + return NULL; + } + + tc = talloc_chunk_from_ptr(ptr); + while (tc->prev) tc=tc->prev; + + return tc->parent; +} + +void *talloc_parent(const void *ptr) +{ + struct talloc_chunk *tc = talloc_parent_chunk(ptr); + return tc? TC_PTR_FROM_CHUNK(tc) : NULL; +} + +/* + find parents name +*/ +const char *talloc_parent_name(const void *ptr) +{ + struct talloc_chunk *tc = talloc_parent_chunk(ptr); + return tc? tc->name : NULL; +} + +/* + A pool carries an in-pool object count count in the first 16 bytes. + bytes. This is done to support talloc_steal() to a parent outside of the + pool. The count includes the pool itself, so a talloc_free() on a pool will + only destroy the pool if the count has dropped to zero. A talloc_free() of a + pool member will reduce the count, and eventually also call free(3) on the + pool memory. + + The object count is not put into "struct talloc_chunk" because it is only + relevant for talloc pools and the alignment to 16 bytes would increase the + memory footprint of each talloc chunk by those 16 bytes. +*/ + +#define TALLOC_POOL_HDR_SIZE 16 + +static unsigned int *talloc_pool_objectcount(struct talloc_chunk *tc) +{ + return (unsigned int *)((char *)tc + sizeof(struct talloc_chunk)); +} + +/* + Allocate from a pool +*/ + +static struct talloc_chunk *talloc_alloc_pool(struct talloc_chunk *parent, + size_t size) +{ + struct talloc_chunk *pool_ctx = NULL; + size_t space_left; + struct talloc_chunk *result; + size_t chunk_size; + + if (parent == NULL) { + return NULL; + } + + if (parent->flags & TALLOC_FLAG_POOL) { + pool_ctx = parent; + } + else if (parent->flags & TALLOC_FLAG_POOLMEM) { + pool_ctx = (struct talloc_chunk *)parent->pool; + } + + if (pool_ctx == NULL) { + return NULL; + } + + space_left = ((char *)pool_ctx + TC_HDR_SIZE + pool_ctx->size) + - ((char *)pool_ctx->pool); + + /* + * Align size to 16 bytes + */ + chunk_size = ((size + 15) & ~15); + + if (space_left < chunk_size) { + return NULL; + } + + result = (struct talloc_chunk *)pool_ctx->pool; + +#if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_UNDEFINED) + VALGRIND_MAKE_MEM_UNDEFINED(result, size); +#endif + + pool_ctx->pool = (void *)((char *)result + chunk_size); + + result->flags = TALLOC_MAGIC | TALLOC_FLAG_POOLMEM; + result->pool = pool_ctx; + + *talloc_pool_objectcount(pool_ctx) += 1; + + return result; +} + +/* + Allocate a bit of memory as a child of an existing pointer +*/ +static inline void *__talloc(const void *context, size_t size) +{ + struct talloc_chunk *tc = NULL; + + if (unlikely(context == NULL)) { + context = null_context; + } + + if (unlikely(size >= MAX_TALLOC_SIZE)) { + abort(); // return NULL; + } + + if (context != NULL) { + tc = talloc_alloc_pool(talloc_chunk_from_ptr(context), + TC_HDR_SIZE+size); + } + + if (tc == NULL) { + tc = (struct talloc_chunk *)malloc(TC_HDR_SIZE+size); + if (unlikely(tc == NULL)) abort(); // return NULL; + tc->flags = TALLOC_MAGIC; + tc->pool = NULL; + } + + tc->size = size; + tc->destructor = NULL; + tc->child = NULL; + tc->name = NULL; + tc->refs = NULL; + + if (likely(context)) { + struct talloc_chunk *parent = talloc_chunk_from_ptr(context); + + if (parent->child) { + parent->child->parent = NULL; + tc->next = parent->child; + tc->next->prev = tc; + } else { + tc->next = NULL; + } + tc->parent = parent; + tc->prev = NULL; + parent->child = tc; + } else { + tc->next = tc->prev = tc->parent = NULL; + } + + return TC_PTR_FROM_CHUNK(tc); +} + +/* + * Create a talloc pool + */ + +void *talloc_pool(const void *context, size_t size) +{ + void *result = __talloc(context, size + TALLOC_POOL_HDR_SIZE); + struct talloc_chunk *tc; + + if (unlikely(result == NULL)) { + return NULL; + } + + tc = talloc_chunk_from_ptr(result); + + tc->flags |= TALLOC_FLAG_POOL; + tc->pool = (char *)result + TALLOC_POOL_HDR_SIZE; + + *talloc_pool_objectcount(tc) = 1; + +#if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_NOACCESS) + VALGRIND_MAKE_MEM_NOACCESS(tc->pool, size); +#endif + + return result; +} + +/* + setup a destructor to be called on free of a pointer + the destructor should return 0 on success, or -1 on failure. + if the destructor fails then the free is failed, and the memory can + be continued to be used +*/ +void _talloc_set_destructor(const void *ptr, int (*destructor)(void *)) +{ + struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr); + tc->destructor = destructor; +} + +/* + increase the reference count on a piece of memory. +*/ +int talloc_increase_ref_count(const void *ptr) +{ + if (unlikely(!talloc_reference(null_context, ptr))) { + return -1; + } + return 0; +} + +/* + helper for talloc_reference() + + this is referenced by a function pointer and should not be inline +*/ +static int talloc_reference_destructor(struct talloc_reference_handle *handle) +{ + struct talloc_chunk *ptr_tc = talloc_chunk_from_ptr(handle->ptr); + _TLIST_REMOVE(ptr_tc->refs, handle); + return 0; +} + +/* + more efficient way to add a name to a pointer - the name must point to a + true string constant +*/ +static inline void _talloc_set_name_const(const void *ptr, const char *name) +{ + struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr); + tc->name = name; +} + +/* + internal talloc_named_const() +*/ +static inline void *_talloc_named_const(const void *context, size_t size, const char *name) +{ + void *ptr; + + ptr = __talloc(context, size); + if (unlikely(ptr == NULL)) { + return NULL; + } + + _talloc_set_name_const(ptr, name); + + return ptr; +} + +/* + make a secondary reference to a pointer, hanging off the given context. + the pointer remains valid until both the original caller and this given + context are freed. + + the major use for this is when two different structures need to reference the + same underlying data, and you want to be able to free the two instances separately, + and in either order +*/ +void *_talloc_reference(const void *context, const void *ptr) +{ + struct talloc_chunk *tc; + struct talloc_reference_handle *handle; + if (unlikely(ptr == NULL)) return NULL; + + tc = talloc_chunk_from_ptr(ptr); + handle = (struct talloc_reference_handle *)_talloc_named_const(context, + sizeof(struct talloc_reference_handle), + TALLOC_MAGIC_REFERENCE); + if (unlikely(handle == NULL)) return NULL; + + /* note that we hang the destructor off the handle, not the + main context as that allows the caller to still setup their + own destructor on the context if they want to */ + talloc_set_destructor(handle, talloc_reference_destructor); + handle->ptr = discard_const_p(void, ptr); + _TLIST_ADD(tc->refs, handle); + return handle->ptr; +} + + +/* + internal talloc_free call +*/ +static inline int _talloc_free(void *ptr) +{ + struct talloc_chunk *tc; + + if (unlikely(ptr == NULL)) { + return -1; + } + + tc = talloc_chunk_from_ptr(ptr); + + if (unlikely(tc->refs)) { + int is_child; + /* check this is a reference from a child or grantchild + * back to it's parent or grantparent + * + * in that case we need to remove the reference and + * call another instance of talloc_free() on the current + * pointer. + */ + is_child = talloc_is_parent(tc->refs, ptr); + _talloc_free(tc->refs); + if (is_child) { + return _talloc_free(ptr); + } + return -1; + } + + if (unlikely(tc->flags & TALLOC_FLAG_LOOP)) { + /* we have a free loop - stop looping */ + return 0; + } + + if (unlikely(tc->destructor)) { + talloc_destructor_t d = tc->destructor; + if (d == (talloc_destructor_t)-1) { + return -1; + } + tc->destructor = (talloc_destructor_t)-1; + if (d(ptr) == -1) { + tc->destructor = d; + return -1; + } + tc->destructor = NULL; + } + + if (tc->parent) { + _TLIST_REMOVE(tc->parent->child, tc); + if (tc->parent->child) { + tc->parent->child->parent = tc->parent; + } + } else { + if (tc->prev) tc->prev->next = tc->next; + if (tc->next) tc->next->prev = tc->prev; + } + + tc->flags |= TALLOC_FLAG_LOOP; + + while (tc->child) { + /* we need to work out who will own an abandoned child + if it cannot be freed. In priority order, the first + choice is owner of any remaining reference to this + pointer, the second choice is our parent, and the + final choice is the null context. */ + void *child = TC_PTR_FROM_CHUNK(tc->child); + const void *new_parent = null_context; + if (unlikely(tc->child->refs)) { + struct talloc_chunk *p = talloc_parent_chunk(tc->child->refs); + if (p) new_parent = TC_PTR_FROM_CHUNK(p); + } + if (unlikely(_talloc_free(child) == -1)) { + if (new_parent == null_context) { + struct talloc_chunk *p = talloc_parent_chunk(ptr); + if (p) new_parent = TC_PTR_FROM_CHUNK(p); + } + talloc_steal(new_parent, child); + } + } + + tc->flags |= TALLOC_FLAG_FREE; + + if (tc->flags & (TALLOC_FLAG_POOL|TALLOC_FLAG_POOLMEM)) { + struct talloc_chunk *pool; + unsigned int *pool_object_count; + + pool = (tc->flags & TALLOC_FLAG_POOL) + ? tc : (struct talloc_chunk *)tc->pool; + + pool_object_count = talloc_pool_objectcount(pool); + + if (*pool_object_count == 0) { + TALLOC_ABORT("Pool object count zero!"); + } + + *pool_object_count -= 1; + + if (*pool_object_count == 0) { + free(pool); + } + } + else { + free(tc); + } + return 0; +} + +/* + move a lump of memory from one talloc context to another return the + ptr on success, or NULL if it could not be transferred. + passing NULL as ptr will always return NULL with no side effects. +*/ +void *_talloc_steal(const void *new_ctx, const void *ptr) +{ + struct talloc_chunk *tc, *new_tc; + + if (unlikely(!ptr)) { + return NULL; + } + + if (unlikely(new_ctx == NULL)) { + new_ctx = null_context; + } + + tc = talloc_chunk_from_ptr(ptr); + + if (unlikely(new_ctx == NULL)) { + if (tc->parent) { + _TLIST_REMOVE(tc->parent->child, tc); + if (tc->parent->child) { + tc->parent->child->parent = tc->parent; + } + } else { + if (tc->prev) tc->prev->next = tc->next; + if (tc->next) tc->next->prev = tc->prev; + } + + tc->parent = tc->next = tc->prev = NULL; + return discard_const_p(void, ptr); + } + + new_tc = talloc_chunk_from_ptr(new_ctx); + + if (unlikely(tc == new_tc || tc->parent == new_tc)) { + return discard_const_p(void, ptr); + } + + if (tc->parent) { + _TLIST_REMOVE(tc->parent->child, tc); + if (tc->parent->child) { + tc->parent->child->parent = tc->parent; + } + } else { + if (tc->prev) tc->prev->next = tc->next; + if (tc->next) tc->next->prev = tc->prev; + } + + tc->parent = new_tc; + if (new_tc->child) new_tc->child->parent = NULL; + _TLIST_ADD(new_tc->child, tc); + + return discard_const_p(void, ptr); +} + + + +/* + remove a secondary reference to a pointer. This undo's what + talloc_reference() has done. The context and pointer arguments + must match those given to a talloc_reference() +*/ +static inline int talloc_unreference(const void *context, const void *ptr) +{ + struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr); + struct talloc_reference_handle *h; + + if (unlikely(context == NULL)) { + context = null_context; + } + + for (h=tc->refs;h;h=h->next) { + struct talloc_chunk *p = talloc_parent_chunk(h); + if (p == NULL) { + if (context == NULL) break; + } else if (TC_PTR_FROM_CHUNK(p) == context) { + break; + } + } + if (h == NULL) { + return -1; + } + + return _talloc_free(h); +} + +/* + remove a specific parent context from a pointer. This is a more + controlled varient of talloc_free() +*/ +int talloc_unlink(const void *context, void *ptr) +{ + struct talloc_chunk *tc_p, *new_p; + void *new_parent; + + if (ptr == NULL) { + return -1; + } + + if (context == NULL) { + context = null_context; + } + + if (talloc_unreference(context, ptr) == 0) { + return 0; + } + + if (context == NULL) { + if (talloc_parent_chunk(ptr) != NULL) { + return -1; + } + } else { + if (talloc_chunk_from_ptr(context) != talloc_parent_chunk(ptr)) { + return -1; + } + } + + tc_p = talloc_chunk_from_ptr(ptr); + + if (tc_p->refs == NULL) { + return _talloc_free(ptr); + } + + new_p = talloc_parent_chunk(tc_p->refs); + if (new_p) { + new_parent = TC_PTR_FROM_CHUNK(new_p); + } else { + new_parent = NULL; + } + + if (talloc_unreference(new_parent, ptr) != 0) { + return -1; + } + + talloc_steal(new_parent, ptr); + + return 0; +} + +/* + add a name to an existing pointer - va_list version +*/ +static inline const char *talloc_set_name_v(const void *ptr, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0); + +static inline const char *talloc_set_name_v(const void *ptr, const char *fmt, va_list ap) +{ + struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr); + tc->name = talloc_vasprintf(ptr, fmt, ap); + if (likely(tc->name)) { + _talloc_set_name_const(tc->name, ".name"); + } + return tc->name; +} + +/* + add a name to an existing pointer +*/ +const char *talloc_set_name(const void *ptr, const char *fmt, ...) +{ + const char *name; + va_list ap; + va_start(ap, fmt); + name = talloc_set_name_v(ptr, fmt, ap); + va_end(ap); + return name; +} + + +/* + create a named talloc pointer. Any talloc pointer can be named, and + talloc_named() operates just like talloc() except that it allows you + to name the pointer. +*/ +void *talloc_named(const void *context, size_t size, const char *fmt, ...) +{ + va_list ap; + void *ptr; + const char *name; + + ptr = __talloc(context, size); + if (unlikely(ptr == NULL)) return NULL; + + va_start(ap, fmt); + name = talloc_set_name_v(ptr, fmt, ap); + va_end(ap); + + if (unlikely(name == NULL)) { + _talloc_free(ptr); + return NULL; + } + + return ptr; +} + +/* + return the name of a talloc ptr, or "UNNAMED" +*/ +const char *talloc_get_name(const void *ptr) +{ + struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr); + if (unlikely(tc->name == TALLOC_MAGIC_REFERENCE)) { + return ".reference"; + } + if (likely(tc->name)) { + return tc->name; + } + return "UNNAMED"; +} + + +/* + check if a pointer has the given name. If it does, return the pointer, + otherwise return NULL +*/ +void *talloc_check_name(const void *ptr, const char *name) +{ + const char *pname; + if (unlikely(ptr == NULL)) return NULL; + pname = talloc_get_name(ptr); + if (likely(pname == name || strcmp(pname, name) == 0)) { + return discard_const_p(void, ptr); + } + return NULL; +} + + +/* + this is for compatibility with older versions of talloc +*/ +void *talloc_init(const char *fmt, ...) +{ + va_list ap; + void *ptr; + const char *name; + + /* + * samba3 expects talloc_report_depth_cb(NULL, ...) + * reports all talloc'ed memory, so we need to enable + * null_tracking + */ + talloc_enable_null_tracking(); + + ptr = __talloc(NULL, 0); + if (unlikely(ptr == NULL)) return NULL; + + va_start(ap, fmt); + name = talloc_set_name_v(ptr, fmt, ap); + va_end(ap); + + if (unlikely(name == NULL)) { + _talloc_free(ptr); + return NULL; + } + + return ptr; +} + +/* + this is a replacement for the Samba3 talloc_destroy_pool functionality. It + should probably not be used in new code. It's in here to keep the talloc + code consistent across Samba 3 and 4. +*/ +void talloc_free_children(void *ptr) +{ + struct talloc_chunk *tc; + + if (unlikely(ptr == NULL)) { + return; + } + + tc = talloc_chunk_from_ptr(ptr); + + while (tc->child) { + /* we need to work out who will own an abandoned child + if it cannot be freed. In priority order, the first + choice is owner of any remaining reference to this + pointer, the second choice is our parent, and the + final choice is the null context. */ + void *child = TC_PTR_FROM_CHUNK(tc->child); + const void *new_parent = null_context; + if (unlikely(tc->child->refs)) { + struct talloc_chunk *p = talloc_parent_chunk(tc->child->refs); + if (p) new_parent = TC_PTR_FROM_CHUNK(p); + } + if (unlikely(_talloc_free(child) == -1)) { + if (new_parent == null_context) { + struct talloc_chunk *p = talloc_parent_chunk(ptr); + if (p) new_parent = TC_PTR_FROM_CHUNK(p); + } + talloc_steal(new_parent, child); + } + } + + if ((tc->flags & TALLOC_FLAG_POOL) + && (*talloc_pool_objectcount(tc) == 1)) { + tc->pool = ((char *)tc + TC_HDR_SIZE + TALLOC_POOL_HDR_SIZE); +#if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_NOACCESS) + VALGRIND_MAKE_MEM_NOACCESS( + tc->pool, tc->size - TALLOC_POOL_HDR_SIZE); +#endif + } +} + +/* + Allocate a bit of memory as a child of an existing pointer +*/ +void *_talloc(const void *context, size_t size) +{ + return __talloc(context, size); +} + +/* + externally callable talloc_set_name_const() +*/ +void talloc_set_name_const(const void *ptr, const char *name) +{ + _talloc_set_name_const(ptr, name); +} + +/* + create a named talloc pointer. Any talloc pointer can be named, and + talloc_named() operates just like talloc() except that it allows you + to name the pointer. +*/ +void *talloc_named_const(const void *context, size_t size, const char *name) +{ + return _talloc_named_const(context, size, name); +} + +/* + free a talloc pointer. This also frees all child pointers of this + pointer recursively + + return 0 if the memory is actually freed, otherwise -1. The memory + will not be freed if the ref_count is > 1 or the destructor (if + any) returns non-zero +*/ +int talloc_free(void *ptr) +{ + return _talloc_free(ptr); +} + + + +/* + A talloc version of realloc. The context argument is only used if + ptr is NULL +*/ +void *_talloc_realloc(const void *context, void *ptr, size_t size, const char *name) +{ + struct talloc_chunk *tc; + void *new_ptr; + bool malloced = false; + + /* size zero is equivalent to free() */ + if (unlikely(size == 0)) { + _talloc_free(ptr); + return NULL; + } + + if (unlikely(size >= MAX_TALLOC_SIZE)) { + abort(); // return NULL; + } + + /* realloc(NULL) is equivalent to malloc() */ + if (ptr == NULL) { + return _talloc_named_const(context, size, name); + } + + tc = talloc_chunk_from_ptr(ptr); + + /* don't allow realloc on referenced pointers */ + if (unlikely(tc->refs)) { + abort(); // return NULL; + } + + /* don't shrink if we have less than 1k to gain */ + if ((size < tc->size) && ((tc->size - size) < 1024)) { + tc->size = size; + return ptr; + } + + /* by resetting magic we catch users of the old memory */ + tc->flags |= TALLOC_FLAG_FREE; + +#if ALWAYS_REALLOC + new_ptr = malloc(size + TC_HDR_SIZE); + if (new_ptr) { + memcpy(new_ptr, tc, tc->size + TC_HDR_SIZE); + free(tc); + } +#else + if (tc->flags & TALLOC_FLAG_POOLMEM) { + + new_ptr = talloc_alloc_pool(tc, size + TC_HDR_SIZE); + *talloc_pool_objectcount((struct talloc_chunk *) + (tc->pool)) -= 1; + + if (new_ptr == NULL) { + new_ptr = malloc(TC_HDR_SIZE+size); + malloced = true; + } + + if (new_ptr) { + memcpy(new_ptr, tc, MIN(tc->size,size) + TC_HDR_SIZE); + } + } + else { + new_ptr = realloc(tc, size + TC_HDR_SIZE); + } +#endif + if (unlikely(!new_ptr)) { + tc->flags &= ~TALLOC_FLAG_FREE; + abort(); // return NULL; + } + + tc = (struct talloc_chunk *)new_ptr; + tc->flags &= ~TALLOC_FLAG_FREE; + if (malloced) { + tc->flags &= ~TALLOC_FLAG_POOLMEM; + } + if (tc->parent) { + tc->parent->child = tc; + } + if (tc->child) { + tc->child->parent = tc; + } + + if (tc->prev) { + tc->prev->next = tc; + } + if (tc->next) { + tc->next->prev = tc; + } + + tc->size = size; + _talloc_set_name_const(TC_PTR_FROM_CHUNK(tc), name); + + return TC_PTR_FROM_CHUNK(tc); +} + +/* + a wrapper around talloc_steal() for situations where you are moving a pointer + between two structures, and want the old pointer to be set to NULL +*/ +void *_talloc_move(const void *new_ctx, const void *_pptr) +{ + const void **pptr = discard_const_p(const void *,_pptr); + void *ret = _talloc_steal(new_ctx, *pptr); + (*pptr) = NULL; + return ret; +} + +/* + return the total size of a talloc pool (subtree) +*/ +size_t talloc_total_size(const void *ptr) +{ + size_t total = 0; + struct talloc_chunk *c, *tc; + + if (ptr == NULL) { + ptr = null_context; + } + if (ptr == NULL) { + return 0; + } + + tc = talloc_chunk_from_ptr(ptr); + + if (tc->flags & TALLOC_FLAG_LOOP) { + return 0; + } + + tc->flags |= TALLOC_FLAG_LOOP; + + total = tc->size; + for (c=tc->child;c;c=c->next) { + total += talloc_total_size(TC_PTR_FROM_CHUNK(c)); + } + + tc->flags &= ~TALLOC_FLAG_LOOP; + + return total; +} + +/* + return the total number of blocks in a talloc pool (subtree) +*/ +size_t talloc_total_blocks(const void *ptr) +{ + size_t total = 0; + struct talloc_chunk *c, *tc = talloc_chunk_from_ptr(ptr); + + if (tc->flags & TALLOC_FLAG_LOOP) { + return 0; + } + + tc->flags |= TALLOC_FLAG_LOOP; + + total++; + for (c=tc->child;c;c=c->next) { + total += talloc_total_blocks(TC_PTR_FROM_CHUNK(c)); + } + + tc->flags &= ~TALLOC_FLAG_LOOP; + + return total; +} + +/* + return the number of external references to a pointer +*/ +size_t talloc_reference_count(const void *ptr) +{ + struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr); + struct talloc_reference_handle *h; + size_t ret = 0; + + for (h=tc->refs;h;h=h->next) { + ret++; + } + return ret; +} + +/* + report on memory usage by all children of a pointer, giving a full tree view +*/ +void talloc_report_depth_cb(const void *ptr, int depth, int max_depth, + void (*callback)(const void *ptr, + int depth, int max_depth, + int is_ref, + void *private_data), + void *private_data) +{ + struct talloc_chunk *c, *tc; + + if (ptr == NULL) { + ptr = null_context; + } + if (ptr == NULL) return; + + tc = talloc_chunk_from_ptr(ptr); + + if (tc->flags & TALLOC_FLAG_LOOP) { + return; + } + + callback(ptr, depth, max_depth, 0, private_data); + + if (max_depth >= 0 && depth >= max_depth) { + return; + } + + tc->flags |= TALLOC_FLAG_LOOP; + for (c=tc->child;c;c=c->next) { + if (c->name == TALLOC_MAGIC_REFERENCE) { + struct talloc_reference_handle *h = (struct talloc_reference_handle *)TC_PTR_FROM_CHUNK(c); + callback(h->ptr, depth + 1, max_depth, 1, private_data); + } else { + talloc_report_depth_cb(TC_PTR_FROM_CHUNK(c), depth + 1, max_depth, callback, private_data); + } + } + tc->flags &= ~TALLOC_FLAG_LOOP; +} + +static void talloc_report_depth_FILE_helper(const void *ptr, int depth, int max_depth, int is_ref, void *_f) +{ + const char *name = talloc_get_name(ptr); + FILE *f = (FILE *)_f; + + if (is_ref) { + fprintf(f, "%*sreference to: %s\n", depth*4, "", name); + return; + } + + if (depth == 0) { + fprintf(f,"%stalloc report on '%s' (total %6lu bytes in %3lu blocks)\n", + (max_depth < 0 ? "full " :""), name, + (unsigned long)talloc_total_size(ptr), + (unsigned long)talloc_total_blocks(ptr)); + return; + } + + fprintf(f, "%*s%-30s contains %6lu bytes in %3lu blocks (ref %d) %p\n", + depth*4, "", + name, + (unsigned long)talloc_total_size(ptr), + (unsigned long)talloc_total_blocks(ptr), + (int)talloc_reference_count(ptr), ptr); + +#if 0 + fprintf(f, "content: "); + if (talloc_total_size(ptr)) { + int tot = talloc_total_size(ptr); + int i; + + for (i = 0; i < tot; i++) { + if ((((char *)ptr)[i] > 31) && (((char *)ptr)[i] < 126)) { + fprintf(f, "%c", ((char *)ptr)[i]); + } else { + fprintf(f, "~%02x", ((char *)ptr)[i]); + } + } + } + fprintf(f, "\n"); +#endif +} + +/* + report on memory usage by all children of a pointer, giving a full tree view +*/ +void talloc_report_depth_file(const void *ptr, int depth, int max_depth, FILE *f) +{ + talloc_report_depth_cb(ptr, depth, max_depth, talloc_report_depth_FILE_helper, f); + fflush(f); +} + +/* + report on memory usage by all children of a pointer, giving a full tree view +*/ +void talloc_report_full(const void *ptr, FILE *f) +{ + talloc_report_depth_file(ptr, 0, -1, f); +} + +/* + report on memory usage by all children of a pointer +*/ +void talloc_report(const void *ptr, FILE *f) +{ + talloc_report_depth_file(ptr, 0, 1, f); +} + +/* + report on any memory hanging off the null context +*/ +static void talloc_report_null(void) +{ + if (talloc_total_size(null_context) != 0) { + talloc_report(null_context, stderr); + } +} + +/* + report on any memory hanging off the null context +*/ +static void talloc_report_null_full(void) +{ + if (talloc_total_size(null_context) != 0) { + talloc_report_full(null_context, stderr); + } +} + +/* + enable tracking of the NULL context +*/ +void talloc_enable_null_tracking(void) +{ + if (null_context == NULL) { + null_context = _talloc_named_const(NULL, 0, "null_context"); + } +} + +/* + disable tracking of the NULL context +*/ +void talloc_disable_null_tracking(void) +{ + _talloc_free(null_context); + null_context = NULL; +} + +/* + enable leak reporting on exit +*/ +void talloc_enable_leak_report(void) +{ + talloc_enable_null_tracking(); + atexit(talloc_report_null); +} + +/* + enable full leak reporting on exit +*/ +void talloc_enable_leak_report_full(void) +{ + talloc_enable_null_tracking(); + atexit(talloc_report_null_full); +} + +/* + talloc and zero memory. +*/ +void *_talloc_zero(const void *ctx, size_t size, const char *name) +{ + void *p = _talloc_named_const(ctx, size, name); + + if (p) { + memset(p, '\0', size); + } + + return p; +} + +/* + memdup with a talloc. +*/ +void *_talloc_memdup(const void *t, const void *p, size_t size, const char *name) +{ + void *newp = _talloc_named_const(t, size, name); + + if (likely(newp)) { + memcpy(newp, p, size); + } + + return newp; +} + +static inline char *__talloc_strlendup(const void *t, const char *p, size_t len) +{ + char *ret; + + ret = (char *)__talloc(t, len + 1); + if (unlikely(!ret)) return NULL; + + memcpy(ret, p, len); + ret[len] = 0; + + _talloc_set_name_const(ret, ret); + return ret; +} + +/* + strdup with a talloc +*/ +char *talloc_strdup(const void *t, const char *p) +{ + if (unlikely(!p)) return NULL; + return __talloc_strlendup(t, p, strlen(p)); +} + +/* + strndup with a talloc +*/ +char *talloc_strndup(const void *t, const char *p, size_t n) +{ + if (unlikely(!p)) return NULL; + return __talloc_strlendup(t, p, strnlen(p, n)); +} + +static inline char *__talloc_strlendup_append(char *s, size_t slen, + const char *a, size_t alen) +{ + char *ret; + + ret = talloc_realloc(NULL, s, char, slen + alen + 1); + if (unlikely(!ret)) return NULL; + + /* append the string and the trailing \0 */ + memcpy(&ret[slen], a, alen); + ret[slen+alen] = 0; + + _talloc_set_name_const(ret, ret); + return ret; +} + +/* + * Appends at the end of the string. + */ +char *talloc_strdup_append(char *s, const char *a) +{ + if (unlikely(!s)) { + return talloc_strdup(NULL, a); + } + + if (unlikely(!a)) { + return s; + } + + return __talloc_strlendup_append(s, strlen(s), a, strlen(a)); +} + +/* + * Appends at the end of the talloc'ed buffer, + * not the end of the string. + */ +char *talloc_strdup_append_buffer(char *s, const char *a) +{ + size_t slen; + + if (unlikely(!s)) { + return talloc_strdup(NULL, a); + } + + if (unlikely(!a)) { + return s; + } + + slen = talloc_get_size(s); + if (likely(slen > 0)) { + slen--; + } + + return __talloc_strlendup_append(s, slen, a, strlen(a)); +} + +/* + * Appends at the end of the string. + */ +char *talloc_strndup_append(char *s, const char *a, size_t n) +{ + if (unlikely(!s)) { + return talloc_strdup(NULL, a); + } + + if (unlikely(!a)) { + return s; + } + + return __talloc_strlendup_append(s, strlen(s), a, strnlen(a, n)); +} + +/* + * Appends at the end of the talloc'ed buffer, + * not the end of the string. + */ +char *talloc_strndup_append_buffer(char *s, const char *a, size_t n) +{ + size_t slen; + + if (unlikely(!s)) { + return talloc_strdup(NULL, a); + } + + if (unlikely(!a)) { + return s; + } + + slen = talloc_get_size(s); + if (likely(slen > 0)) { + slen--; + } + + return __talloc_strlendup_append(s, slen, a, strnlen(a, n)); +} + +#ifndef HAVE_VA_COPY +#ifdef HAVE___VA_COPY +#define va_copy(dest, src) __va_copy(dest, src) +#else +#define va_copy(dest, src) (dest) = (src) +#endif +#endif + +char *talloc_vasprintf(const void *t, const char *fmt, va_list ap) +{ + int len; + char *ret; + va_list ap2; + char c; + + /* this call looks strange, but it makes it work on older solaris boxes */ + va_copy(ap2, ap); + len = vsnprintf(&c, 1, fmt, ap2); + va_end(ap2); + if (unlikely(len < 0)) { + abort(); // return NULL; + } + + ret = (char *)__talloc(t, len+1); + if (unlikely(!ret)) return NULL; + + va_copy(ap2, ap); + vsnprintf(ret, len+1, fmt, ap2); + va_end(ap2); + + _talloc_set_name_const(ret, ret); + return ret; +} + + +/* + Perform string formatting, and return a pointer to newly allocated + memory holding the result, inside a memory pool. + */ +char *talloc_asprintf(const void *t, const char *fmt, ...) +{ + va_list ap; + char *ret; + + va_start(ap, fmt); + ret = talloc_vasprintf(t, fmt, ap); + va_end(ap); + return ret; +} + +static inline char *__talloc_vaslenprintf_append(char *s, size_t slen, + const char *fmt, va_list ap) + PRINTF_ATTRIBUTE(3,0); + +static inline char *__talloc_vaslenprintf_append(char *s, size_t slen, + const char *fmt, va_list ap) +{ + ssize_t alen; + va_list ap2; + char c; + + va_copy(ap2, ap); + alen = vsnprintf(&c, 1, fmt, ap2); + va_end(ap2); + + if (alen <= 0) { + /* Either the vsnprintf failed or the format resulted in + * no characters being formatted. In the former case, we + * ought to return NULL, in the latter we ought to return + * the original string. Most current callers of this + * function expect it to never return NULL. + */ + return s; + } + + s = talloc_realloc(NULL, s, char, slen + alen + 1); + if (!s) return NULL; + + va_copy(ap2, ap); + vsnprintf(s + slen, alen + 1, fmt, ap2); + va_end(ap2); + + _talloc_set_name_const(s, s); + return s; +} + +/** + * Realloc @p s to append the formatted result of @p fmt and @p ap, + * and return @p s, which may have moved. Good for gradually + * accumulating output into a string buffer. Appends at the end + * of the string. + **/ +char *talloc_vasprintf_append(char *s, const char *fmt, va_list ap) +{ + if (unlikely(!s)) { + return talloc_vasprintf(NULL, fmt, ap); + } + + return __talloc_vaslenprintf_append(s, strlen(s), fmt, ap); +} + +/** + * Realloc @p s to append the formatted result of @p fmt and @p ap, + * and return @p s, which may have moved. Always appends at the + * end of the talloc'ed buffer, not the end of the string. + **/ +char *talloc_vasprintf_append_buffer(char *s, const char *fmt, va_list ap) +{ + size_t slen; + + if (unlikely(!s)) { + return talloc_vasprintf(NULL, fmt, ap); + } + + slen = talloc_get_size(s); + if (likely(slen > 0)) { + slen--; + } + + return __talloc_vaslenprintf_append(s, slen, fmt, ap); +} + +/* + Realloc @p s to append the formatted result of @p fmt and return @p + s, which may have moved. Good for gradually accumulating output + into a string buffer. + */ +char *talloc_asprintf_append(char *s, const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + s = talloc_vasprintf_append(s, fmt, ap); + va_end(ap); + return s; +} + +/* + Realloc @p s to append the formatted result of @p fmt and return @p + s, which may have moved. Good for gradually accumulating output + into a buffer. + */ +char *talloc_asprintf_append_buffer(char *s, const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + s = talloc_vasprintf_append_buffer(s, fmt, ap); + va_end(ap); + return s; +} + +/* + alloc an array, checking for integer overflow in the array size +*/ +void *_talloc_array(const void *ctx, size_t el_size, unsigned count, const char *name) +{ + if (count >= MAX_TALLOC_SIZE/el_size) { + abort(); // return NULL; + } + return _talloc_named_const(ctx, el_size * count, name); +} + +/* + alloc an zero array, checking for integer overflow in the array size +*/ +void *_talloc_zero_array(const void *ctx, size_t el_size, unsigned count, const char *name) +{ + if (count >= MAX_TALLOC_SIZE/el_size) { + abort(); // return NULL; + } + return _talloc_zero(ctx, el_size * count, name); +} + +/* + realloc an array, checking for integer overflow in the array size +*/ +void *_talloc_realloc_array(const void *ctx, void *ptr, size_t el_size, unsigned count, const char *name) +{ + if (count >= MAX_TALLOC_SIZE/el_size) { + abort(); // return NULL; + } + return _talloc_realloc(ctx, ptr, el_size * count, name); +} + +/* + a function version of talloc_realloc(), so it can be passed as a function pointer + to libraries that want a realloc function (a realloc function encapsulates + all the basic capabilities of an allocation library, which is why this is useful) +*/ +void *talloc_realloc_fn(const void *context, void *ptr, size_t size) +{ + return _talloc_realloc(context, ptr, size, NULL); +} + + +static int talloc_autofree_destructor(void *ptr) +{ + autofree_context = NULL; + return 0; +} + +static void talloc_autofree(void) +{ + _talloc_free(autofree_context); +} + +/* + return a context which will be auto-freed on exit + this is useful for reducing the noise in leak reports +*/ +void *talloc_autofree_context(void) +{ + if (autofree_context == NULL) { + autofree_context = _talloc_named_const(NULL, 0, "autofree_context"); + talloc_set_destructor(autofree_context, talloc_autofree_destructor); + atexit(talloc_autofree); + } + return autofree_context; +} + +size_t talloc_get_size(const void *context) +{ + struct talloc_chunk *tc; + + if (context == NULL) + return 0; + + tc = talloc_chunk_from_ptr(context); + + return tc->size; +} + +/* + find a parent of this context that has the given name, if any +*/ +void *talloc_find_parent_byname(const void *context, const char *name) +{ + struct talloc_chunk *tc; + + if (context == NULL) { + return NULL; + } + + tc = talloc_chunk_from_ptr(context); + while (tc) { + if (tc->name && strcmp(tc->name, name) == 0) { + return TC_PTR_FROM_CHUNK(tc); + } + while (tc && tc->prev) tc = tc->prev; + if (tc) { + tc = tc->parent; + } + } + return NULL; +} + +/* + show the parentage of a context +*/ +void talloc_show_parents(const void *context, FILE *file) +{ + struct talloc_chunk *tc; + + if (context == NULL) { + fprintf(file, "talloc no parents for NULL\n"); + return; + } + + tc = talloc_chunk_from_ptr(context); + fprintf(file, "talloc parents of '%s'\n", talloc_get_name(context)); + while (tc) { + fprintf(file, "\t'%s'\n", talloc_get_name(TC_PTR_FROM_CHUNK(tc))); + while (tc && tc->prev) tc = tc->prev; + if (tc) { + tc = tc->parent; + } + } + fflush(file); +} + +/* + return 1 if ptr is a parent of context +*/ +int talloc_is_parent(const void *context, const void *ptr) +{ + struct talloc_chunk *tc; + + if (context == NULL) { + return 0; + } + + tc = talloc_chunk_from_ptr(context); + while (tc) { + if (TC_PTR_FROM_CHUNK(tc) == ptr) return 1; + while (tc && tc->prev) tc = tc->prev; + if (tc) { + tc = tc->parent; + } + } + return 0; +} diff --git a/talloc.h b/talloc.h new file mode 100644 index 0000000000..5431971655 --- /dev/null +++ b/talloc.h @@ -0,0 +1,183 @@ +#ifndef _TALLOC_H_ +#define _TALLOC_H_ +/* + Unix SMB/CIFS implementation. + Samba temporary memory allocation functions + + Copyright (C) Andrew Tridgell 2004-2005 + Copyright (C) Stefan Metzmacher 2006 + + ** NOTE! The following LGPL license applies to the talloc + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see <http://www.gnu.org/licenses/>. +*/ + +#include <stdlib.h> +#include <stdio.h> +#include <stdarg.h> + +/* this is only needed for compatibility with the old talloc */ +typedef void TALLOC_CTX; + +/* + this uses a little trick to allow __LINE__ to be stringified +*/ +#ifndef __location__ +#define __TALLOC_STRING_LINE1__(s) #s +#define __TALLOC_STRING_LINE2__(s) __TALLOC_STRING_LINE1__(s) +#define __TALLOC_STRING_LINE3__ __TALLOC_STRING_LINE2__(__LINE__) +#define __location__ __FILE__ ":" __TALLOC_STRING_LINE3__ +#endif + +#ifndef TALLOC_DEPRECATED +#define TALLOC_DEPRECATED 0 +#endif + +#ifndef PRINTF_ATTRIBUTE +#if (__GNUC__ >= 3) +/** Use gcc attribute to check printf fns. a1 is the 1-based index of + * the parameter containing the format, and a2 the index of the first + * argument. Note that some gcc 2.x versions don't handle this + * properly **/ +#define PRINTF_ATTRIBUTE(a1, a2) __attribute__ ((format (__printf__, a1, a2))) +#else +#define PRINTF_ATTRIBUTE(a1, a2) +#endif +#endif + +/* try to make talloc_set_destructor() and talloc_steal() type safe, + if we have a recent gcc */ +#if (__GNUC__ >= 3) +#define _TALLOC_TYPEOF(ptr) __typeof__(ptr) +#define talloc_set_destructor(ptr, function) \ + do { \ + int (*_talloc_destructor_fn)(_TALLOC_TYPEOF(ptr)) = (function); \ + _talloc_set_destructor((ptr), (int (*)(void *))_talloc_destructor_fn); \ + } while(0) +/* this extremely strange macro is to avoid some braindamaged warning + stupidity in gcc 4.1.x */ +#define talloc_steal(ctx, ptr) ({ _TALLOC_TYPEOF(ptr) __talloc_steal_ret = (_TALLOC_TYPEOF(ptr))_talloc_steal((ctx),(ptr)); __talloc_steal_ret; }) +#else +#define talloc_set_destructor(ptr, function) \ + _talloc_set_destructor((ptr), (int (*)(void *))(function)) +#define _TALLOC_TYPEOF(ptr) void * +#define talloc_steal(ctx, ptr) (_TALLOC_TYPEOF(ptr))_talloc_steal((ctx),(ptr)) +#endif + +#define talloc_reference(ctx, ptr) (_TALLOC_TYPEOF(ptr))_talloc_reference((ctx),(ptr)) +#define talloc_move(ctx, ptr) (_TALLOC_TYPEOF(*(ptr)))_talloc_move((ctx),(void *)(ptr)) + +/* useful macros for creating type checked pointers */ +#define talloc(ctx, type) (type *)talloc_named_const(ctx, sizeof(type), #type) +#define talloc_size(ctx, size) talloc_named_const(ctx, size, __location__) +#define talloc_ptrtype(ctx, ptr) (_TALLOC_TYPEOF(ptr))talloc_size(ctx, sizeof(*(ptr))) + +#define talloc_new(ctx) talloc_named_const(ctx, 0, "talloc_new: " __location__) + +#define talloc_zero(ctx, type) (type *)_talloc_zero(ctx, sizeof(type), #type) +#define talloc_zero_size(ctx, size) _talloc_zero(ctx, size, __location__) + +#define talloc_zero_array(ctx, type, count) (type *)_talloc_zero_array(ctx, sizeof(type), count, #type) +#define talloc_array(ctx, type, count) (type *)_talloc_array(ctx, sizeof(type), count, #type) +#define talloc_array_size(ctx, size, count) _talloc_array(ctx, size, count, __location__) +#define talloc_array_ptrtype(ctx, ptr, count) (_TALLOC_TYPEOF(ptr))talloc_array_size(ctx, sizeof(*(ptr)), count) + +#define talloc_realloc(ctx, p, type, count) (type *)_talloc_realloc_array(ctx, p, sizeof(type), count, #type) +#define talloc_realloc_size(ctx, ptr, size) _talloc_realloc(ctx, ptr, size, __location__) + +#define talloc_memdup(t, p, size) _talloc_memdup(t, p, size, __location__) + +#define talloc_set_type(ptr, type) talloc_set_name_const(ptr, #type) +#define talloc_get_type(ptr, type) (type *)talloc_check_name(ptr, #type) + +#define talloc_find_parent_bytype(ptr, type) (type *)talloc_find_parent_byname(ptr, #type) + +#if TALLOC_DEPRECATED +#define talloc_zero_p(ctx, type) talloc_zero(ctx, type) +#define talloc_p(ctx, type) talloc(ctx, type) +#define talloc_array_p(ctx, type, count) talloc_array(ctx, type, count) +#define talloc_realloc_p(ctx, p, type, count) talloc_realloc(ctx, p, type, count) +#define talloc_destroy(ctx) talloc_free(ctx) +#define talloc_append_string(c, s, a) (s?talloc_strdup_append(s,a):talloc_strdup(c, a)) +#endif + +/* The following definitions come from talloc.c */ +void *_talloc(const void *context, size_t size); +void *talloc_pool(const void *context, size_t size); +void _talloc_set_destructor(const void *ptr, int (*destructor)(void *)); +int talloc_increase_ref_count(const void *ptr); +size_t talloc_reference_count(const void *ptr); +void *_talloc_reference(const void *context, const void *ptr); +int talloc_unlink(const void *context, void *ptr); +const char *talloc_set_name(const void *ptr, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3); +void talloc_set_name_const(const void *ptr, const char *name); +void *talloc_named(const void *context, size_t size, + const char *fmt, ...) PRINTF_ATTRIBUTE(3,4); +void *talloc_named_const(const void *context, size_t size, const char *name); +const char *talloc_get_name(const void *ptr); +void *talloc_check_name(const void *ptr, const char *name); +void *talloc_parent(const void *ptr); +const char *talloc_parent_name(const void *ptr); +void *talloc_init(const char *fmt, ...) PRINTF_ATTRIBUTE(1,2); +int talloc_free(void *ptr); +void talloc_free_children(void *ptr); +void *_talloc_realloc(const void *context, void *ptr, size_t size, const char *name); +void *_talloc_steal(const void *new_ctx, const void *ptr); +void *_talloc_move(const void *new_ctx, const void *pptr); +size_t talloc_total_size(const void *ptr); +size_t talloc_total_blocks(const void *ptr); +void talloc_report_depth_cb(const void *ptr, int depth, int max_depth, + void (*callback)(const void *ptr, + int depth, int max_depth, + int is_ref, + void *private_data), + void *private_data); +void talloc_report_depth_file(const void *ptr, int depth, int max_depth, FILE *f); +void talloc_report_full(const void *ptr, FILE *f); +void talloc_report(const void *ptr, FILE *f); +void talloc_enable_null_tracking(void); +void talloc_disable_null_tracking(void); +void talloc_enable_leak_report(void); +void talloc_enable_leak_report_full(void); +void *_talloc_zero(const void *ctx, size_t size, const char *name); +void *_talloc_memdup(const void *t, const void *p, size_t size, const char *name); +void *_talloc_array(const void *ctx, size_t el_size, unsigned count, const char *name); +void *_talloc_zero_array(const void *ctx, size_t el_size, unsigned count, const char *name); +void *_talloc_realloc_array(const void *ctx, void *ptr, size_t el_size, unsigned count, const char *name); +void *talloc_realloc_fn(const void *context, void *ptr, size_t size); +void *talloc_autofree_context(void); +size_t talloc_get_size(const void *ctx); +void *talloc_find_parent_byname(const void *ctx, const char *name); +void talloc_show_parents(const void *context, FILE *file); +int talloc_is_parent(const void *context, const void *ptr); + +char *talloc_strdup(const void *t, const char *p); +char *talloc_strdup_append(char *s, const char *a); +char *talloc_strdup_append_buffer(char *s, const char *a); + +char *talloc_strndup(const void *t, const char *p, size_t n); +char *talloc_strndup_append(char *s, const char *a, size_t n); +char *talloc_strndup_append_buffer(char *s, const char *a, size_t n); + +char *talloc_vasprintf(const void *t, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0); +char *talloc_vasprintf_append(char *s, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0); +char *talloc_vasprintf_append_buffer(char *s, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0); + +char *talloc_asprintf(const void *t, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3); +char *talloc_asprintf_append(char *s, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3); +char *talloc_asprintf_append_buffer(char *s, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3); + +#endif diff --git a/vidix/.gitignore b/vidix/.gitignore new file mode 100644 index 0000000000..96d02a288a --- /dev/null +++ b/vidix/.gitignore @@ -0,0 +1,5 @@ +/pci_dev_ids.c +/pci_ids.h +/pci_names.c +/pci_names.h +/pci_vendors.h diff --git a/vidix/drivers.c b/vidix/drivers.c index 2311d94800..6d427b1e2b 100644 --- a/vidix/drivers.c +++ b/vidix/drivers.c @@ -24,6 +24,7 @@ #include <errno.h> #include <string.h> +#include "drivers.h" #include "config.h" #include "vidix.h" #include "libavutil/common.h" diff --git a/vidix/nvidia_vid.c b/vidix/nvidia_vid.c index 767a358f37..4c86322932 100644 --- a/vidix/nvidia_vid.c +++ b/vidix/nvidia_vid.c @@ -441,12 +441,12 @@ struct rivatv_info { }; typedef struct rivatv_info rivatv_info; -uint8_t nvReadVGA (struct rivatv_chip *chip, int index) { +static uint8_t nvReadVGA (struct rivatv_chip *chip, int index) { VID_WR08 (chip->PCIO, 0x3D4, index); return VID_RD08 (chip->PCIO, 0x3D5); } -void nvWriteVGA (struct rivatv_chip *chip, int index, int data) { +static void nvWriteVGA (struct rivatv_chip *chip, int index, int data) { VID_WR08 (chip->PCIO, 0x3D4, index); VID_WR08 (chip->PCIO, 0x3D5, data); } |