diff options
Diffstat (limited to 'debian/transcode/transcode-1.1.7/libtc')
44 files changed, 12748 insertions, 0 deletions
diff --git a/debian/transcode/transcode-1.1.7/libtc/Makefile.am b/debian/transcode/transcode-1.1.7/libtc/Makefile.am new file mode 100644 index 00000000..70271bbe --- /dev/null +++ b/debian/transcode/transcode-1.1.7/libtc/Makefile.am @@ -0,0 +1,65 @@ +# # Process this file with automake to produce Makefile.in. + +AM_CPPFLAGS = \ + $(PTHREAD_CFLAGS) \ + -I$(top_srcdir) \ + -I$(top_srcdir)/src + +noinst_LTLIBRARIES = libtc.la + +if !HAVE_GETOPT_LONG_ONLY +GETOPT_FILES = getopt.c getopt1.c +endif + +if HAVE_IBP +XIO_FILES = libxio.c +endif + +if HAVE_GETTIMEOFDAY +TIMER_FILES = tctimer.c +endif + +libtc_la_SOURCES = \ + cfgfile.c \ + framecode.c \ + iodir.c \ + optstr.c \ + ratiocodes.c \ + strlcat.c \ + strlcpy.c \ + tc_functions.c \ + tccodecs.c \ + tcframes.c \ + tcglob.c \ + tclist.c \ + tcmodule.c \ + tcmoduleinfo.c \ + $(GETOPT_FILES) \ + $(TIMER_FILES) \ + $(XIO_FILES) + +EXTRA_DIST = \ + cfgfile.h \ + framecode.h \ + getopt.h \ + iodir.h \ + libtc.h \ + optstr.h \ + ratiocodes.h \ + static_xio.h \ + static_optstr.h \ + static_tclist.h \ + static_tctimer.h \ + tc_lzo.h \ + tcavcodec.h \ + tccodecs.h \ + tcformats.h \ + tcframes.h \ + tcglob.h \ + tclist.h \ + tcmodule-core.h \ + tcmodule-data.h \ + tcmodule-info.h \ + tcmodule-plugin.h \ + tctimer.h \ + xio.h diff --git a/debian/transcode/transcode-1.1.7/libtc/Makefile.in b/debian/transcode/transcode-1.1.7/libtc/Makefile.in new file mode 100644 index 00000000..9a73b59c --- /dev/null +++ b/debian/transcode/transcode-1.1.7/libtc/Makefile.in @@ -0,0 +1,656 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +# # Process this file with automake to produce Makefile.in. + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +target_triplet = @target@ +subdir = libtc +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +LTLIBRARIES = $(noinst_LTLIBRARIES) +libtc_la_LIBADD = +am__libtc_la_SOURCES_DIST = cfgfile.c framecode.c iodir.c optstr.c \ + ratiocodes.c strlcat.c strlcpy.c tc_functions.c tccodecs.c \ + tcframes.c tcglob.c tclist.c tcmodule.c tcmoduleinfo.c \ + getopt.c getopt1.c tctimer.c libxio.c +@HAVE_GETOPT_LONG_ONLY_FALSE@am__objects_1 = getopt.lo getopt1.lo +@HAVE_GETTIMEOFDAY_TRUE@am__objects_2 = tctimer.lo +@HAVE_IBP_TRUE@am__objects_3 = libxio.lo +am_libtc_la_OBJECTS = cfgfile.lo framecode.lo iodir.lo optstr.lo \ + ratiocodes.lo strlcat.lo strlcpy.lo tc_functions.lo \ + tccodecs.lo tcframes.lo tcglob.lo tclist.lo tcmodule.lo \ + tcmoduleinfo.lo $(am__objects_1) $(am__objects_2) \ + $(am__objects_3) +libtc_la_OBJECTS = $(am_libtc_la_OBJECTS) +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/autotools/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(libtc_la_SOURCES) +DIST_SOURCES = $(am__libtc_la_SOURCES_DIST) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +A52_CFLAGS = @A52_CFLAGS@ +A52_LIBS = @A52_LIBS@ +ACLIB_LIBS = @ACLIB_LIBS@ +ACLOCAL = @ACLOCAL@ +ALTIVEC_CFLAGS = @ALTIVEC_CFLAGS@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AVILIB_LIBS = @AVILIB_LIBS@ +AWK = @AWK@ +BSDAV_CFLAGS = @BSDAV_CFLAGS@ +BSDAV_LIBS = @BSDAV_LIBS@ +CC = @CC@ +CCAS = @CCAS@ +CCASDEPMODE = @CCASDEPMODE@ +CCASFLAGS = @CCASFLAGS@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXXCPP = @CXXCPP@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLDARWIN_CFLAGS = @DLDARWIN_CFLAGS@ +DLDARWIN_LIBS = @DLDARWIN_LIBS@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FAAC_CFLAGS = @FAAC_CFLAGS@ +FAAC_LIBS = @FAAC_LIBS@ +FGREP = @FGREP@ +FREETYPE2_CFLAGS = @FREETYPE2_CFLAGS@ +FREETYPE2_LIBS = @FREETYPE2_LIBS@ +GREP = @GREP@ +IBP_LIBS = @IBP_LIBS@ +ICONV_CFLAGS = @ICONV_CFLAGS@ +ICONV_LIBS = @ICONV_LIBS@ +IMAGEMAGICK_CFLAGS = @IMAGEMAGICK_CFLAGS@ +IMAGEMAGICK_LIBS = @IMAGEMAGICK_LIBS@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LAME_CFLAGS = @LAME_CFLAGS@ +LAME_LIBS = @LAME_LIBS@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBAVCODEC_CFLAGS = @LIBAVCODEC_CFLAGS@ +LIBAVCODEC_LIBS = @LIBAVCODEC_LIBS@ +LIBAVFORMAT_CFLAGS = @LIBAVFORMAT_CFLAGS@ +LIBAVFORMAT_LIBS = @LIBAVFORMAT_LIBS@ +LIBDVDREAD_CFLAGS = @LIBDVDREAD_CFLAGS@ +LIBDVDREAD_LIBS = @LIBDVDREAD_LIBS@ +LIBDV_CFLAGS = @LIBDV_CFLAGS@ +LIBDV_LIBS = @LIBDV_LIBS@ +LIBJPEG_CFLAGS = @LIBJPEG_CFLAGS@ +LIBJPEG_LIBS = @LIBJPEG_LIBS@ +LIBMPEG2CONVERT_CFLAGS = @LIBMPEG2CONVERT_CFLAGS@ +LIBMPEG2CONVERT_LIBS = @LIBMPEG2CONVERT_LIBS@ +LIBMPEG2_CFLAGS = @LIBMPEG2_CFLAGS@ +LIBMPEG2_LIBS = @LIBMPEG2_LIBS@ +LIBOBJS = @LIBOBJS@ +LIBPOSTPROC_CFLAGS = @LIBPOSTPROC_CFLAGS@ +LIBPOSTPROC_LIBS = @LIBPOSTPROC_LIBS@ +LIBQUICKTIME_CFLAGS = @LIBQUICKTIME_CFLAGS@ +LIBQUICKTIME_LIBS = @LIBQUICKTIME_LIBS@ +LIBS = @LIBS@ +LIBTCAUDIO_LIBS = @LIBTCAUDIO_LIBS@ +LIBTCVIDEO_LIBS = @LIBTCVIDEO_LIBS@ +LIBTC_LIBS = @LIBTC_LIBS@ +LIBTOOL = @LIBTOOL@ +LIBV4L2_CFLAGS = @LIBV4L2_CFLAGS@ +LIBV4L2_LIBS = @LIBV4L2_LIBS@ +LIBV4LCONVERT_CFLAGS = @LIBV4LCONVERT_CFLAGS@ +LIBV4LCONVERT_LIBS = @LIBV4LCONVERT_LIBS@ +LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ +LIBXML2_LIBS = @LIBXML2_LIBS@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LZO_CFLAGS = @LZO_CFLAGS@ +LZO_LIBS = @LZO_LIBS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MJPEGTOOLS_CFLAGS = @MJPEGTOOLS_CFLAGS@ +MJPEGTOOLS_LIBS = @MJPEGTOOLS_LIBS@ +MKDIR_P = @MKDIR_P@ +MOD_PATH = @MOD_PATH@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OGG_CFLAGS = @OGG_CFLAGS@ +OGG_LIBS = @OGG_LIBS@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PATH_TO_AWK = @PATH_TO_AWK@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +PROF_PATH = @PROF_PATH@ +PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ +PTHREAD_LIBS = @PTHREAD_LIBS@ +PVM3_CFLAGS = @PVM3_CFLAGS@ +PVM3_LIBS = @PVM3_LIBS@ +PVM3_PVMGS = @PVM3_PVMGS@ +RANLIB = @RANLIB@ +SDL_CFLAGS = @SDL_CFLAGS@ +SDL_LIBS = @SDL_LIBS@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SIMD_FLAGS = @SIMD_FLAGS@ +STRIP = @STRIP@ +THEORA_CFLAGS = @THEORA_CFLAGS@ +THEORA_LIBS = @THEORA_LIBS@ +USE_DLDARWIN = @USE_DLDARWIN@ +VERSION = @VERSION@ +VORBIS_CFLAGS = @VORBIS_CFLAGS@ +VORBIS_LIBS = @VORBIS_LIBS@ +WAVLIB_LIBS = @WAVLIB_LIBS@ +X264_CFLAGS = @X264_CFLAGS@ +X264_LIBS = @X264_LIBS@ +XIO_CFLAGS = @XIO_CFLAGS@ +XIO_LIBS = @XIO_LIBS@ +XMKMF = @XMKMF@ +XVID_CFLAGS = @XVID_CFLAGS@ +XVID_LIBS = @XVID_LIBS@ +X_CFLAGS = @X_CFLAGS@ +X_EXTRA_LIBS = @X_EXTRA_LIBS@ +X_LIBS = @X_LIBS@ +X_PRE_LIBS = @X_PRE_LIBS@ +a52_config = @a52_config@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +bsdav_config = @bsdav_config@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +faac_config = @faac_config@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +iconv_config = @iconv_config@ +imagemagick_config = @imagemagick_config@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +lame_config = @lame_config@ +libdir = @libdir@ +libdvdread_config = @libdvdread_config@ +libexecdir = @libexecdir@ +libjpeg_config = @libjpeg_config@ +libjpegmmx_config = @libjpegmmx_config@ +localedir = @localedir@ +localstatedir = @localstatedir@ +lzo_config = @lzo_config@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +pvm3_config = @pvm3_config@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +x_includes = @x_includes@ +x_libraries = @x_libraries@ +xvid_config = @xvid_config@ +AM_CPPFLAGS = \ + $(PTHREAD_CFLAGS) \ + -I$(top_srcdir) \ + -I$(top_srcdir)/src + +noinst_LTLIBRARIES = libtc.la +@HAVE_GETOPT_LONG_ONLY_FALSE@GETOPT_FILES = getopt.c getopt1.c +@HAVE_IBP_TRUE@XIO_FILES = libxio.c +@HAVE_GETTIMEOFDAY_TRUE@TIMER_FILES = tctimer.c +libtc_la_SOURCES = \ + cfgfile.c \ + framecode.c \ + iodir.c \ + optstr.c \ + ratiocodes.c \ + strlcat.c \ + strlcpy.c \ + tc_functions.c \ + tccodecs.c \ + tcframes.c \ + tcglob.c \ + tclist.c \ + tcmodule.c \ + tcmoduleinfo.c \ + $(GETOPT_FILES) \ + $(TIMER_FILES) \ + $(XIO_FILES) + +EXTRA_DIST = \ + cfgfile.h \ + framecode.h \ + getopt.h \ + iodir.h \ + libtc.h \ + optstr.h \ + ratiocodes.h \ + static_xio.h \ + static_optstr.h \ + static_tclist.h \ + static_tctimer.h \ + tc_lzo.h \ + tcavcodec.h \ + tccodecs.h \ + tcformats.h \ + tcframes.h \ + tcglob.h \ + tclist.h \ + tcmodule-core.h \ + tcmodule-data.h \ + tcmodule-info.h \ + tcmodule-plugin.h \ + tctimer.h \ + xio.h + +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu libtc/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu libtc/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstLTLIBRARIES: + -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) + @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +libtc.la: $(libtc_la_OBJECTS) $(libtc_la_DEPENDENCIES) + $(LINK) $(libtc_la_OBJECTS) $(libtc_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cfgfile.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/framecode.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getopt.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getopt1.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/iodir.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libxio.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/optstr.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ratiocodes.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/strlcat.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/strlcpy.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc_functions.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tccodecs.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tcframes.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tcglob.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tclist.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tcmodule.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tcmoduleinfo.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tctimer.Plo@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-noinstLTLIBRARIES ctags distclean \ + distclean-compile distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ + pdf pdf-am ps ps-am tags uninstall uninstall-am + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/debian/transcode/transcode-1.1.7/libtc/cfgfile.c b/debian/transcode/transcode-1.1.7/libtc/cfgfile.c new file mode 100644 index 00000000..ca0331ce --- /dev/null +++ b/debian/transcode/transcode-1.1.7/libtc/cfgfile.c @@ -0,0 +1,697 @@ +/* + * cfgfile.c -- routines to handle external configuration files + * Written by Andrew Church <achurch@achurch.org> + * + * This file is part of transcode, a video stream processing tool. + * transcode is free software, distributable under the terms of the GNU + * General Public License (version 2 or later). See the file COPYING + * for details. + */ + +#define _ISOC99_SOURCE /* needed by glibc to declare strtof() */ + +#include "transcode.h" +#include "libtc.h" +#include "cfgfile.h" + +#include <stdlib.h> +#include <string.h> +#include <ctype.h> + +static char *config_dir = NULL; + +static int parse_line(const char *buf, TCConfigEntry *conf, const char *tag, + const char *filename, int line); +static void parse_line_error(const char *buf, const char *filename, int line, + const char *tag, const char *format, ...) +#ifdef HAVE_GCC_ATTRIBUTES +__attribute__((format(printf,5,6))) +#endif +; + +/*************************************************************************/ +/* helpers macros and functions */ + +#define CLEANUP_LINE(line) do { \ + /* skip comments, if any */ \ + char *s = strchr((line), '#'); \ + if (s) { \ + *s = 0; \ + } \ + /* Remove leading and trailing spaces, if any */ \ + tc_strstrip((line)); \ +} while (0) + +/** + * fopen_verbose: Opens a configuration file in read only mode, printing + * meaningful error messages in case of failure. + * + * Parameters: + * name: Name of configuration file to open. + * tag: Tag to use in log messages. + * Return value: + * Read-only FILE pointer to configuration file, NULL if failed. + */ + + +static FILE *fopen_verbose(const char *name, const char *tag) +{ + FILE *f = fopen(name, "r"); + if (!f) { + if (errno == EEXIST) { + tc_log_warn(tag, "Configuration file %s does not exist!", + name); + } else if (errno == EACCES) { + tc_log_warn(tag, "Configuration file %s cannot be read!", + name); + } else { + tc_log_warn(tag, "Error opening configuration file %s: %s", + name, strerror(errno)); + } + } + return f; +} + +/** + * lookup_section: Move FILE pointer to begining of data belonging to + * given section. + * + * Parameters: + * f: Already open FILE pointer to configuration file. + * section: Name of section to lookup. + * tag: Tag to use in log messages. + * Return value: + * number of lines skipped (>= 0) if succesfull. + * < 0 if error occurs. + */ +static int lookup_section(FILE *f, const char *section, const char *tag) +{ + char expect[TC_BUF_MAX], buf[TC_BUF_MAX]; + int line = 0; + + tc_snprintf(expect, sizeof(expect), "[%s]", section); + do { + if (!fgets(buf, sizeof(buf), f)) { + tc_log_warn(tag, "Section [%s] not found in configuration" + " file!", section); + return -1; + } + line++; + CLEANUP_LINE(buf); + } while (strcmp(buf, expect) != 0); + return line; +} + +/*************************************************************************/ + +/** + * tc_set_config_dir: Sets the directory in which configuration files are + * searched for. + * + * Parameters: + * dir: Directory to search for configuration files in. If NULL, the + * current directory is used. + * Return value: + * None. + */ + +void tc_set_config_dir(const char *dir) +{ + tc_free(config_dir); + config_dir = dir ? tc_strdup(dir) : NULL; +} + + +/*************************************************************************/ + +/** + * module_read_config: Reads in configuration information from an external + * file. + * + * Parameters: + * filename: Name of the configuration file to read. + * section: Section to read within the file, or NULL to read the + * entire file regardless of sections. + * conf: Array of configuration entries. + * tag: Tag to use in log messages. + * Return value: + * Nonzero on success, zero on failure. + */ + +int module_read_config(const char *filename, const char *section, + TCConfigEntry *conf, const char *tag) +{ + char buf[TC_BUF_MAX], path_buf[PATH_MAX+1]; + FILE *f = NULL; + int line = 0; + + /* Sanity checks */ + if (!tag) + tag = __FILE__; + if (!filename || !conf) { + tc_log_error(tag, "module_read_config(): %s == NULL!", + !filename ? "filename" : !conf ? "conf" : "???"); + return 0; + } + + /* Open the file */ + tc_snprintf(path_buf, sizeof(path_buf), "%s/%s", + config_dir ? config_dir : ".", filename); + f = fopen_verbose(path_buf, tag); + if (!f) { + return 0; + } + + if (section) { + line = lookup_section(f, section, tag); + if (line == -1) { + /* error */ + fclose(f); + return 0; + } + } + + /* Read in the configuration values (up to the end of the section, if + * a section name was given) */ + while (fgets(buf, sizeof(buf), f)) { + line++; + CLEANUP_LINE(buf); + + /* Ignore empty lines and comment lines */ + if (!*buf || *buf == '#') + continue; + + /* If it's a section name, this is the end of the current section */ + if (*buf == '[') { + if (section) + break; + else + continue; + } + + /* Pass it on to the parser */ + parse_line(buf, conf, tag, path_buf, line); + } + + fclose(f); + return 1; +} + +/*************************************************************************/ + +/** + * module_read_config_line: Processes a string as if it were a line read + * from a configuration file. The string must have all leading and + * trailing whitespace stripped. + * + * Parameters: + * string: String to process. + * conf: Array of configuration entries. + * tag: Tag to use in log messages. + * Return value: + * Nonzero if the string was successfully processed, else zero. + */ + +int module_read_config_line(const char *string, TCConfigEntry *conf, + const char *tag) +{ + if (!tag) + tag = __FILE__; + if (!string || !conf) { + tc_log_error(tag, "module_read_config_line(): %s == NULL!", + !string ? "string" : !conf ? "conf" : "???"); + return 0; + } + return parse_line(string, conf, tag, NULL, 0); +} + +/*************************************************************************/ + +/** + * module_print_config: Prints the given array of configuration data. + * + * Parameters: + * conf: Array of configuration data. + * tag: Tag to use in log messages. + * Return value: + * None. + */ + +void module_print_config(const TCConfigEntry *conf, const char *tag) +{ + /* Sanity checks */ + if (!tag) + tag = __FILE__; + if (!conf) { + tc_log_error(tag, "module_print_config(): conf == NULL!"); + return; + } + + while (conf->name) { + char buf[TC_BUF_MAX]; + switch (conf->type) { + case TCCONF_TYPE_FLAG: + tc_snprintf(buf, sizeof(buf), "%d", *((int *)conf->ptr) ? 1 : 0); + break; + case TCCONF_TYPE_INT: + tc_snprintf(buf, sizeof(buf), "%d", *((int *)conf->ptr)); + break; + case TCCONF_TYPE_FLOAT: + tc_snprintf(buf, sizeof(buf), "%f", *((float *)conf->ptr)); + break; + case TCCONF_TYPE_STRING: + tc_snprintf(buf, sizeof(buf), "%s", *((char **)conf->ptr)); + break; + } + tc_log_info(tag, "%s = %s", conf->name, buf); + conf++; + } +} + +/*************************************************************************/ +/*************************************************************************/ + +/** + * parse_line: Internal routine to parse a single line of a configuration + * file and set the appropriate variable. + * + * Parameters: + * buf: Line to process. Leading and trailing whitespace + * (including newlines) are assumed to have been stripped. + * conf: Array of configuration entries. + * tag: Tag to use in log messages. + * filename: Name of file being processed, or NULL if none. + * line: Current line number in file. + * Return value: + * Nonzero if the buffer was successfully parsed, else 0. + * Preconditions: + * buf != NULL + * conf != NULL + * tag != NULL + */ + +static int parse_line(const char *buf, TCConfigEntry *conf, const char *tag, + const char *filename, int line) +{ + char workbuf[TC_BUF_MAX]; + char *name, *value, *s; + + /* Make a working copy of the string */ + if (strlcpy(workbuf, buf, sizeof(workbuf)) >= sizeof(workbuf)) { + parse_line_error(buf, filename, line, tag, + "Buffer overflow while parsing configuration data"); + return 0; + } + + /* Split string into name and value */ + name = workbuf; + s = strchr(workbuf, '='); + if (s) { + value = s+1; + while (s > workbuf && isspace(s[-1])) + s--; + *s = 0; + while (isspace(*value)) + value++; + } else { + value = NULL; + } + if (!*name) { + parse_line_error(buf, filename, line, tag, + "Syntax error in option (missing variable name)"); + return 0; + } else if (value && !*value) { + parse_line_error(buf, filename, line, tag, + "Syntax error in option (missing value)"); + return 0; + } + + /* Look for a matching configuration entry */ + while (conf->name) { + if (strcmp(conf->name, name) == 0) + break; + conf++; + } + if (!conf->name) { + parse_line_error(buf, filename, line, tag, + "Unknown configuration variable `%s'", name); + return 0; + } + /* Make sure non-flag entries have values */ + if (conf->type != TCCONF_TYPE_FLAG && !value) { + parse_line_error(buf, filename, line, tag, + "Syntax error in option (missing value)"); + return 0; + } + + /* Set the value appropriately */ + + switch (conf->type) { + case TCCONF_TYPE_FLAG: + if (!value + || strcmp(value,"1" ) == 0 + || strcmp(value,"yes" ) == 0 + || strcmp(value,"on " ) == 0 + || strcmp(value,"true") == 0 + ) { + *((int *)(conf->ptr)) = (int)conf->max; + } else if (strcmp(value,"0" ) == 0 + || strcmp(value,"no" ) == 0 + || strcmp(value,"off" ) == 0 + || strcmp(value,"false") == 0 + ) { + *((int *)(conf->ptr)) = 0; + } else { + parse_line_error(buf, filename, line, tag, + "Value for variable `%s' must be either 1 or 0", + name); + return 0; + } + break; + + case TCCONF_TYPE_INT: { + long lvalue; + errno = 0; + lvalue = strtol(value, &value, 0); + if (*value) { + parse_line_error(buf, filename, line, tag, + "Value for variable `%s' must be an integer", + name); + return 0; + } else if (errno == ERANGE +#if LONG_MIN < INT_MIN + || lvalue < INT_MIN +#endif +#if LONG_MAX < INT_MAX + || lvalue > INT_MAX +#endif + || ((conf->flags & TCCONF_FLAG_MIN) && lvalue < conf->min) + || ((conf->flags & TCCONF_FLAG_MAX) && lvalue > conf->max) + ) { + parse_line_error(buf, filename, line, tag, + "Value for variable `%s' is out of range", name); + return 0; + } else { + *((int *)(conf->ptr)) = (int)lvalue; + } + break; + } + + case TCCONF_TYPE_FLOAT: { + float fvalue; + errno = 0; +#ifdef HAVE_STRTOF + fvalue = strtof(value, &value); +#else + fvalue = (float)strtod(value, &value); +#endif + if (*value) { + parse_line_error(buf, filename, line, tag, + "Value for variable `%s' must be a number", name); + return 0; + } else if (errno == ERANGE + || ((conf->flags & TCCONF_FLAG_MIN) && fvalue < conf->min) + || ((conf->flags & TCCONF_FLAG_MAX) && fvalue > conf->max) + ) { + parse_line_error(buf, filename, line, tag, + "Value for variable `%s' is out of range", name); + return 0; + } else { + *((float *)(conf->ptr)) = fvalue; + } + break; + } + + case TCCONF_TYPE_STRING: { + char *newval = tc_strdup(value); + if (!newval) { + parse_line_error(buf, filename, line, tag, + "Out of memory setting variable `%s'", name); + return 0; + } else { + *((char **)(conf->ptr)) = newval; + } + break; + } + + default: + parse_line_error(buf, filename, line, tag, + "Unknown type %d for variable `%s' (bug?)", + conf->type, name); + return 0; + + } /* switch (conf->type) */ + + return 1; +} + +/*************************************************************************/ + +/** + * parse_line_error: Helper routine for parse_line() to print an error + * message, formatted appropriately depending on whether a filename was + * given or not. + * + * Parameters: + * buf: String that caused the error. + * filename: Name of file being processed, or NULL if none. + * line: Current line number in file. + * tag: Tag to use in log message. + * format: Format string for message. + * Return value: + * None. + * Preconditions: + * buf != NULL + * tag != NULL + * format != NULL + */ + +static void parse_line_error(const char *buf, const char *filename, int line, + const char *tag, const char *format, ...) +{ + char msgbuf[TC_BUF_MAX]; + va_list args; + + va_start(args, format); + tc_vsnprintf(msgbuf, sizeof(msgbuf), format, args); + va_end(args); + if (filename) { + tc_log_warn(tag, "%s:%d: %s", filename, line, msgbuf); + } else { + tc_log_warn(tag, "\"%s\": %s", buf, msgbuf); + } +} + +/*************************************************************************/ + +/** + * list_new: create a new list item storing a copy of given data string. + * + * Parameters: + * value: string to copy into new list item. + * Return value: + * pointer to new list item if succesfull. + * NULL otherwise. + */ + +static TCConfigList *list_new(const char *value) +{ + TCConfigList *list = tc_malloc(sizeof(TCConfigList)); + if (list) { + list->next = NULL; + list->last = NULL; + list->value = NULL; + + if (value) { + list->value = tc_strdup(value); + if (!list->value) { + tc_free(list); + list = NULL; + } + } + } + return list; +} + +/** + * list_append: append a new item storing given data on a given list. + * + * Parameters: + * list: list to append new item + * value: value to be copied into new item + * Return value: + * 0 succesfull + * !0 error + */ + +static int list_append(TCConfigList *list, const char *value) +{ + int ret = 1; + TCConfigList *item = list_new(value); + if (item) { + if (list->last != NULL) { + /* typical case */ + list->last->next = item; + } else { + /* second item, special case */ + list->next = item; + } + list->last = item; + + ret = 0; + } + return ret; +} + +/** + * module_read_config_list: Read a list section from given configuration + * file and return the corresponding data list. + * + * Parameters: + * filename: Name of file being processed. + * section: Name of the section to be read. + * tag: Tag to use in log message. + * Return value: + * A pointer to a valid configuration list structure if succesfull, + * NULL otherwise. + */ + +TCConfigList *module_read_config_list(const char *filename, + const char *section, const char *tag) +{ + char buf[TC_BUF_MAX], path_buf[PATH_MAX+1]; + TCConfigList *list = NULL; + FILE *f = NULL; + int line = 0; + + /* Sanity checks */ + if (!tag) + tag = __FILE__; + if (!filename) { + tc_log_error(tag, "module_read_config(): missing filename"); + return 0; + } + if (!section) { + tc_log_error(tag, "module_read_config(): missing section"); + return 0; + } + + /* Open the file */ + tc_snprintf(path_buf, sizeof(path_buf), "%s/%s", + config_dir ? config_dir : ".", filename); + f = fopen_verbose(path_buf, tag); + if (!f) { + return NULL; + } + line = lookup_section(f, section, tag); + if (line == -1) { + /* error */ + fclose(f); + return NULL; + } + + /* Read in the configuration values (up to the end of the section, if + * a section name was given) */ + while (fgets(buf, sizeof(buf), f)) { + line++; + CLEANUP_LINE(buf); + + /* Ignore empty lines and comment lines */ + if (!*buf || *buf == '#') + continue; + + /* If it's a section name, this is the end of the current section */ + if (*buf == '[') { + break; + } else { + int err = 1; + + if (list) { + err = list_append(list, buf); + } else { + list = list_new(buf); + err = (list == NULL) ?1 :0; + } + + if (err) { + tc_log_error(tag, "out of memory at line %i", line); + module_free_config_list(list, 0); + list = NULL; + } + } + } + + fclose(f); + return list; +} + +/** + * module_free_config_list: Dispose a configuration list created by + * module_read_config_list. + * + * Parameters: + * list: Head of configuration list to free. + * refonly: If !0, DO NOT free data pointed to list; + * If 0, free list itslef AND data as well. + * Recap: use 0 to free everything, use !0 if you + * do want to preserve data for some reasons. + * Return value: + * None. + */ + +void module_free_config_list(TCConfigList *list, int refonly) +{ + TCConfigList *item = NULL; + while (list) { + item = list->next; + if (!refonly) { + tc_free((void*)list->value); + } + tc_free(list); + list = item; + } +} + +/** + * module_print_config_list: Prints the given configuration list. + * + * Parameters: + * list: Head of configuration list. + * section: Name of section on which configuration list belongs. + * tag: Tag to use in log messages. + * Return value: + * None. + */ + +void module_print_config_list(const TCConfigList *list, + const char *section, const char *tag) +{ + /* Sanity checks */ + if (!tag) + tag = __FILE__; + if (!section) { + tc_log_error(tag, "module_print_config_list(): section == NULL!"); + return; + } + if (!list) { + tc_log_error(tag, "module_print_config_list(): list == NULL!"); + return; + } + + tc_log_info(tag, "[%s]", section); + for (; list != NULL; list = list->next) { + tc_log_info(tag, "%s", list->value); + } +} + +/*************************************************************************/ + +/* + * Local variables: + * c-file-style: "stroustrup" + * c-file-offsets: ((case-label . *) (statement-case-intro . *)) + * indent-tabs-mode: nil + * End: + * + * vim: expandtab shiftwidth=4: + */ diff --git a/debian/transcode/transcode-1.1.7/libtc/cfgfile.h b/debian/transcode/transcode-1.1.7/libtc/cfgfile.h new file mode 100644 index 00000000..7a1e4b77 --- /dev/null +++ b/debian/transcode/transcode-1.1.7/libtc/cfgfile.h @@ -0,0 +1,87 @@ +/* + * cfgfile.h -- include for configuration file handling + * Written by Andrew Church <achurch@achurch.org> + * + * This file is part of transcode, a video stream processing tool. + * transcode is free software, distributable under the terms of the GNU + * General Public License (version 2 or later). See the file COPYING + * for details. + */ + +#ifndef LIBTC_CFGFILE_H +#define LIBTC_CFGFILE_H + +/*************************************************************************/ + +/* Configuration entry types */ +typedef enum { + TCCONF_TYPE_FLAG, /* type int */ + TCCONF_TYPE_INT, /* type int */ + TCCONF_TYPE_FLOAT, /* type float */ + TCCONF_TYPE_STRING, /* type char * (memory will be allocated) */ +} TCConfigEntryType; + + +/* Structure of a configuration entry. An array of these, as passed to the + * functions below, ends with an entry with name==NULL. */ +typedef struct { + const char *name; /* Name used in configuration file */ + void *ptr; /* Pointer to value */ + TCConfigEntryType type; + int flags; /* TCCONF_FLAG_* below */ + double min, max; /* Used when FLAG_MIN or FLAG_MAX are set */ +} TCConfigEntry; + +#define TCCONF_FLAG_MIN (1<<0) +#define TCCONF_FLAG_MAX (1<<1) +#define TCCONF_FLAG_RANGE (1<<0) + +/*************************************************************************/ + +/* Set the directory used to find configuration files. */ +void tc_set_config_dir(const char *dir); + +/* Read module configuration data from the given file. */ +int module_read_config(const char *filename, const char *section, + TCConfigEntry *conf, const char *tag); + +/* Process a string as if it were a line from a configuration file. */ +int module_read_config_line(const char *string, TCConfigEntry *conf, + const char *tag); + +/* Print module configuration data. */ +void module_print_config(const TCConfigEntry *conf, const char *tag); + +/*************************************************************************/ + +typedef struct tcconfiglist_ TCConfigList; +struct tcconfiglist_ { + char *value; + TCConfigList *next; + TCConfigList *last; +}; + +/* Read a List section of a configuration file. Triggered by PVM module. */ +TCConfigList *module_read_config_list(const char *filename, + const char *section, const char *tag); + +/* Print module configuration list for a given section */ +void module_print_config_list(const TCConfigList *list, + const char *section, const char *tag); + +/* Dispose a configuration list produced by read_config_list */ +void module_free_config_list(TCConfigList *list, int refonly); + +/*************************************************************************/ + +#endif /* LIBTC_CFGFILE_H */ + +/* + * Local variables: + * c-file-style: "stroustrup" + * c-file-offsets: ((case-label . *) (statement-case-intro . *)) + * indent-tabs-mode: nil + * End: + * + * vim: expandtab shiftwidth=4: + */ diff --git a/debian/transcode/transcode-1.1.7/libtc/framecode.c b/debian/transcode/transcode-1.1.7/libtc/framecode.c new file mode 100644 index 00000000..aba1f69a --- /dev/null +++ b/debian/transcode/transcode-1.1.7/libtc/framecode.c @@ -0,0 +1,509 @@ +/* + * framecode.c -- framecode list handling + * Written by Andrew Church <achurch@achurch.org> + * + * This file is part of transcode, a video stream processing tool. + * transcode is free software, distributable under the terms of the GNU + * General Public License (version 2 or later). See the file COPYING + * for details. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> +#include <limits.h> /* for UINT_MAX and ULONG_MAX */ +#include <math.h> + +#include "libtc.h" +#include "framecode.h" + +/* Internal function prototypes: */ +static void normalize_fc_time(struct fc_time *range); +static struct fc_time *parse_one_range(const char *string, double fps, + const char **errmsg_ret, + int *errpos_ret); +static int parse_one_time(const char **strptr, unsigned int *hour_ret, + unsigned int *min_ret, unsigned int *sec_ret, + unsigned int *frame_ret, const char **errmsg_ret); +static int parse_one_value(const char **strptr, unsigned int *value_ret, + const char **errmsg_ret); + +/*************************************************************************/ +/************************** External interface ***************************/ +/*************************************************************************/ + +/** + * new_fc_time: Allocate a new, zeroed fc_time structure. + * + * Parameters: + * None. + * Return value: + * The allocated fc_time structure, or NULL on failure. + * Side effects: + * Prints an error message if allocation fails. + */ + +struct fc_time *new_fc_time(void) +{ + return tc_zalloc(sizeof(struct fc_time)); +} + +/*************************************************************************/ + +/** + * free_fc_time: Free a list of allocated fc_time structures. + * + * Parameters: + * list: The list of structures to free. + * Return value: + * None. + */ + +void free_fc_time(struct fc_time *list) +{ + while (list) { + struct fc_time *temp = list->next; + free(list); + list = temp; + } +} + +/*************************************************************************/ + +/** + * set_fc_time: Set fields of an fc_time structure from frame indices. + * + * Parameters: + * range: The fc_time structure to modify. + * start: The frame index for the start time, or -1 for no change. + * end: The frame index for the end time, or -1 for no change. + * Return value: + * None. + * Side effects: + * Prints an error message if the `range' parameter is invalid (either + * the parameter is NULL or it points to a range whose `fps' field is + * not a positive value). + */ + +void set_fc_time(struct fc_time *range, int start, int end) +{ + if (!range || range->fps <= 0) { + tc_log_error(__FILE__, "set_fc_time() with invalid range!"); + return; + } + if (start >= 0) { + range->sh = 0; + range->sm = 0; + range->ss = 0; + range->sf = start; + } + if (end >= 0) { + range->eh = 0; + range->em = 0; + range->es = 0; + range->ef = end; + } + normalize_fc_time(range); +} + +/*************************************************************************/ + +/** + * fc_time_contains: Return whether a list of fc_time structures contains + * a given frame index. + * + * Parameters: + * list: List of fc_time structures to check. + * frame: Frame index. + * Return value: + * Nonzero if one of the ranges contains the given frame index, else 0. + */ + +int fc_time_contains(const struct fc_time *list, unsigned int frame) +{ + while (list) { + if (frame >= list->stf && frame < list->etf) + return 1; + list = list->next; + } + return 0; +} + +/*************************************************************************/ + +/** + * new_fc_time_from_string: Parse a string into a list of fc_time + * structures. + * + * Parameters: + * string: The string to parse. + * separator: A string containing separators for distinct ranges + * within `string'. + * fps: The value to store in each range's `fps' field. + * verbose: If positive, each range will be printed as it is parsed. + * If negative, error messages will be suppressed. + * Return value: + * The list of fc_time structures on success, NULL on failure. + * Side effects: + * Prints an error message if parsing fails, unless verbose < 0. + */ + +struct fc_time *new_fc_time_from_string(const char *string, + const char *separator, + double fps, int verbose) +{ + struct fc_time *list, *tail; + char rangebuf[101]; /* Buffer to hold a single range for processing */ + const char *s; + + /* Sanity checks first */ + if (!string) { + if (verbose >= 0) { + tc_log_error(__FILE__, + "new_fc_time_from_string(): string is NULL!"); + } + return NULL; + } + if (!separator) { + if (verbose >= 0) { + tc_log_error(__FILE__, + "new_fc_time_from_string(): separator is NULL!"); + } + return NULL; + } + if (fps <= 0) { + if (verbose >= 0) { + tc_log_error(__FILE__, "new_fc_time_from_string(): fps <= 0!"); + } + return NULL; + } + + /* Loop through all ranges in the string */ + list = tail = NULL; + s = string + strspn(string,separator); + while (*s) { + struct fc_time *range; /* Newly-allocated fc_time structure */ + const char *errmsg; /* Error message from parse_one_range() */ + int errpos; /* Position of error within range string */ + const char *t; + + t = s + strcspn(s,separator); + if (t-s > sizeof(rangebuf)-1) { + if (verbose >= 0) { + tc_log_error(__FILE__, "new_fc_time_from_string():" + " range string too long! (%u/%u)", + (unsigned)(t-s), (unsigned)sizeof(rangebuf)-1); + /* Print out the string and the location of the error */ + tc_log_error(__FILE__, "%s", string); + tc_log_error(__FILE__, "%*s", (int)((s-string)+1), "^"); + } + /* Don't forget to free anything we already parsed */ + free_fc_time(list); + return NULL; + } + memcpy(rangebuf, s, t-s); + rangebuf[t-s] = 0; + errmsg = "unknown error"; + errpos = 0; + range = parse_one_range(rangebuf, fps, &errmsg, &errpos); + if (!range) { + if (verbose >= 0) { + tc_log_error(__FILE__, "Error parsing framecode range: %s", + errmsg); + tc_log_error(__FILE__, "%s", string); + tc_log_error(__FILE__, "%*s", (int)((s-string+errpos)+1), "^"); + } + free_fc_time(list); + return NULL; + } + if (verbose > 0) { + tc_log_info(__FILE__, "Range: %u:%02u:%02u.%u (%u)" + " - %u:%02u:%02u.%u (%u)", + range->sh, range->sm, range->ss, range->sf, + range->stf, + range->eh, range->em, range->es, range->ef, + range->etf); + } + if (!list) { + list = tail = range; + } else { + tail->next = range; + tail = range; + } + s = t + strspn(t,separator); + } + + /* Parsing completed successfully */ + return list; +} + +/*************************************************************************/ +/************************** Internal functions ***************************/ +/*************************************************************************/ + +/** + * normalize_fc_time: Convert the HH:MM:SS.FF times stored in the given + * fc_time structure to a normalized form, with MM < 60, SS < 60, and + * FF < range->fps; also, store the frame indices corresponding to the + * start and end times in range->stf and range->etf, respectively. + * Fractional frame numbers are rounded down to the next lowest integer. + * Used by set_fc_time() and parse_one_range(). + * + * Parameters: + * range: fc_time structure to normalize. + * Return value: + * None. + * Preconditions: + * range != NULL + * range->fps > 0 + */ + +static void normalize_fc_time(struct fc_time *range) +{ + /* Calculate frame index from time parameters (round down) */ + range->stf = floor(((range->sh * 60 + range->sm) * 60 + range->ss) + * range->fps) + + range->sf; + /* Calculate total number of seconds */ + range->ss = (unsigned int)floor(range->stf / range->fps); + /* Calculate frame remainder */ + range->sf = (unsigned int)floor(range->stf - (range->ss * range->fps)); + /* Calculate normalized hours, minutes, and seconds */ + range->sh = range->ss / 3600; + range->sm = (range->ss/60) % 60; + range->ss %= 60; + + /* Repeat for end time */ + range->etf = floor(((range->eh * 60 + range->em) * 60 + range->es) + * range->fps) + + range->ef; + range->es = (unsigned int)floor(range->etf / range->fps); + range->ef = (unsigned int)floor(range->etf - (range->es * range->fps)); + range->eh = range->es / 3600; + range->em = (range->es/60) % 60; + range->es %= 60; +} + +/*************************************************************************/ + +/** + * parse_one_range: Parse a string containing a single framecode range, + * and return a newly allocated fc_time structure containing the range. + * Used by new_fc_time_from_string(). + * + * Parameters: + * string: String to parse. + * fps: Frames-per-second value to use for the range. + * errmsg_ret: Pointer to location to store error message in. On + * failure, this is filled with a pointer to an error + * message; on success, the value is not modified. + * errpos_ret: Pointer to location to store error position in. On + * failure, this is filled with the offset in characters + * from the start of the string to the position at which + * the error occurred; on success, the value is not + * modified. + * Return value: + * The newly-allocated fc_time structure, or NULL on error. + * Preconditions: + * string != NULL + * fps > 0 + * errmsg_ret != NULL + * errpos_ret != NULL + */ + +static struct fc_time *parse_one_range(const char *string, double fps, + const char **errmsg_ret, + int *errpos_ret) +{ + struct fc_time *range; /* New fc_time structure */ + const char *s = string; /* Current parsing location */ + + /* Allocate new (cleared) fc_time and set FPS */ + range = new_fc_time(); + if (!range) { + *errmsg_ret = "out of memory"; + *errpos_ret = 0; + return NULL; + } + range->fps = fps; + range->stepf = 1; + + /* Parse start time */ + if (!parse_one_time(&s, &range->sh, &range->sm, &range->ss, &range->sf, + errmsg_ret)) + goto error; + + /* Check for and skip intervening hyphen */ + if (*s != '-') { + *errmsg_ret = "syntax error (expected '-')"; + goto error; + } + s++; + + /* Parse end time */ + if (!parse_one_time(&s, &range->eh, &range->em, &range->es, &range->ef, + errmsg_ret)) + goto error; + + /* Parse step value, if present */ + if (*s == '/') { + s++; + if (!parse_one_value(&s, &range->stepf, errmsg_ret)) + goto error; + } + + /* Make sure we're at the end of the string */ + if (*s) { + *errmsg_ret = "garbage at end of range"; + goto error; + } + + /* Successfully parsed: normalize values and return */ + normalize_fc_time(range); + return range; + + error: + *errpos_ret = s - string; + free_fc_time(range); + return NULL; +} + +/*************************************************************************/ + +/** + * parse_one_time: Parse an [[[HH:]MM:]SS.]FF time specification. + * + * Parameters: + * strptr: Pointer to the string to be parsed. + * hour_ret: Pointer to variable to receive the parsed hour value. + * The stored value is unchanged on error. + * min_ret: Pointer to variable to receive the parsed minute value. + * The stored value is unchanged on error. + * sec_ret: Pointer to variable to receive the parsed second value. + * The stored value is unchanged on error. + * frame_ret: Pointer to variable to receive the parsed frame value. + * The stored value is unchanged on error. + * errmsg_ret: As for parse_one_range(). + * Return value: + * Nonzero if parsing succeeded, zero on error. + * Preconditions: + * strptr != NULL + * *strptr != NULL + * hour_ret != NULL + * min_ret != NULL + * sec_ret != NULL + * frame_ret != NULL + * errmsg_ret != NULL + * Side effects: + * `*strptr' is advanced to the first character beyond the parsed + * string on success; on failure, the stored value points to the + * location of the error. + */ + +static int parse_one_time(const char **strptr, unsigned int *hour_ret, + unsigned int *min_ret, unsigned int *sec_ret, + unsigned int *frame_ret, const char **errmsg_ret) +{ + unsigned int hour = 0, min = 0, sec = 0, frame = 0; + int saw_colon = 0; /* for deciding whether it's a bare frame count */ + + if (!parse_one_value(strptr, &hour, errmsg_ret)) + return 0; + if (**strptr == ':') { + saw_colon = 1; + (*strptr)++; + if (!parse_one_value(strptr, &min, errmsg_ret)) + return 0; + if (**strptr == ':') { + (*strptr)++; + if (!parse_one_value(strptr, &sec, errmsg_ret)) + return 0; + } else { + sec = min; + min = hour; + hour = 0; + } + } else { + sec = hour; + hour = 0; + } + if (**strptr == '.') { + (*strptr)++; + if (!parse_one_value(strptr, &frame, errmsg_ret)) + return 0; + } else if (!saw_colon) { + /* No colon or dot--must be a bare frame count */ + frame = sec; + sec = 0; + } + + /* Success */ + *hour_ret = hour; + *min_ret = min; + *sec_ret = sec; + *frame_ret = frame; + return 1; +} + +/*************************************************************************/ + +/** + * parse_one_value: Parse a single base-10 nonnegative integer value from + * the given string. Used by parse_one_range(). + * + * Parameters: + * strptr: Pointer to the string to be parsed. + * value_ret: Pointer to variable to receive the parsed value. The + * stored value is unchanged on error. + * errmsg_ret: As for parse_one_range(). + * Return value: + * Nonzero if parsing succeeded, zero on error. + * Preconditions: + * strptr != NULL + * *strptr != NULL + * value_ret != NULL + * errmsg_ret != NULL + * Side effects: + * `*strptr' is advanced to the first character beyond the parsed + * string on success; on failure, the stored value is unchanged. + */ + +static int parse_one_value(const char **strptr, unsigned int *value_ret, + const char **errmsg_ret) +{ + const char *s; + unsigned long lvalue; + + errno = 0; + lvalue = (unsigned int)strtoul(*strptr, (char **)&s, 10); + if (s == *strptr) { + *errmsg_ret = "not a valid number"; + return 0; + } else if (errno == ERANGE +#if ULONG_MAX > UINT_MAX + || lvalue > UINT_MAX +#endif + ) { + *errmsg_ret = "value out of range"; + return 0; + } + *strptr = s; + *value_ret = (unsigned int)lvalue; + return 1; +} + +/*************************************************************************/ + +/* + * Local variables: + * c-file-style: "stroustrup" + * c-file-offsets: ((case-label . *) (statement-case-intro . *)) + * indent-tabs-mode: nil + * End: + * + * vim: expandtab shiftwidth=4: + */ diff --git a/debian/transcode/transcode-1.1.7/libtc/framecode.h b/debian/transcode/transcode-1.1.7/libtc/framecode.h new file mode 100644 index 00000000..72faccf1 --- /dev/null +++ b/debian/transcode/transcode-1.1.7/libtc/framecode.h @@ -0,0 +1,85 @@ +/* + * framecode.h -- framecode list handling include file + * Written by Andrew Church <achurch@achurch.org> + * + * This file is part of transcode, a video stream processing tool. + * transcode is free software, distributable under the terms of the GNU + * General Public License (version 2 or later). See the file COPYING + * for details. + */ + +#ifndef LIBTC_FRAMECODE_H +#define LIBTC_FRAMECODE_H + +/*************************************************************************/ + +/* A single framecode range structure. Start times are considered + * inclusive, while end times are considered exclusive; thus a range with + * stf==0 and etf==10 contains 10 frames, not 11 frames. */ + +struct fc_time { + struct fc_time *next; + + double fps; /* Frames per second */ + unsigned int stepf; /* Step value (process every stepf'th frame) */ + unsigned int vob_offset; /* For transcode -L (should be removed) */ + + unsigned int sh; /* Start time: hour */ + unsigned int sm; /* Start time: minute */ + unsigned int ss; /* Start time: second */ + unsigned int sf; /* Start time: frame within second */ + unsigned int stf; /* Start time: frame index */ + + unsigned int eh; /* End time: hour */ + unsigned int em; /* End time: minute */ + unsigned int es; /* End time: second */ + unsigned int ef; /* End time: frame within second */ + unsigned int etf; /* End time: frame index */ +}; + +/*************************************************************************/ + +/* Functions for handling fc_time structures. */ + + +/* Allocate a new, zeroed fc_time structure. */ +struct fc_time *new_fc_time(void); + +/* Free a list of allocated fc_time structures. */ +void free_fc_time(struct fc_time *list); + +/* Set fields of an fc_time structure from frame indices. */ +void set_fc_time(struct fc_time *range, int start, int end); + +/* Return whether a list of fc_time structures contains a given frame index. */ +int fc_time_contains(const struct fc_time *list, unsigned int frame); + +/* Parse a string into a list of fc_time structures. */ +struct fc_time *new_fc_time_from_string(const char *string, + const char *separator, + double fps, int verbose); + + +/* Compatibility macros */ + +#define parse_fc_time_string(str,fps,sep,verb,list) \ + ((*(list) = new_fc_time_from_string((str), (sep), (fps), (verb))) \ + != NULL ? 0 : -1) +#define fc_frame_in_time(list,frame) fc_time_contains((list), (frame)) + +// only for avisplit +#define fc_set_start_time(range,n) set_fc_time((range), (n), -1) + +/*************************************************************************/ + +#endif /* LIBTC_FRAMECODE_H */ + +/* + * Local variables: + * c-file-style: "stroustrup" + * c-file-offsets: ((case-label . *) (statement-case-intro . *)) + * indent-tabs-mode: nil + * End: + * + * vim: expandtab shiftwidth=4: + */ diff --git a/debian/transcode/transcode-1.1.7/libtc/getopt.c b/debian/transcode/transcode-1.1.7/libtc/getopt.c new file mode 100644 index 00000000..d176d3e7 --- /dev/null +++ b/debian/transcode/transcode-1.1.7/libtc/getopt.c @@ -0,0 +1,1049 @@ +/* Getopt for GNU. + NOTE: The canonical source of this file is maintained with the GNU + C Library. Bugs can be reported to bug-glibc@gnu.org. + + Copyright (C) 1987, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99 + Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, or (at your option) any + later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +/* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>. + Ditto for AIX 3.2 and <stdlib.h>. */ +#ifndef _NO_PROTO +# define _NO_PROTO +#endif + +#ifdef HAVE_CONFIG_H +# include <config.h> +#else +# if !defined __STDC__ || !__STDC__ +/* This is a separate conditional since some stdc systems + reject `defined (const)'. */ +# ifndef const +# define const +# endif +# endif +#endif + +#include <stdio.h> + +/* Comment out all this code if we are using the GNU C Library, and are not + actually compiling the library itself. This code is part of the GNU C + Library, but also included in many other GNU distributions. Compiling + and linking in this code is a waste when using the GNU C library + (especially if it is a shared library). Rather than having every GNU + program understand `configure --with-gnu-libc' and omit the object files, + it is simpler to just do this in the source for each such file. */ + +#define GETOPT_INTERFACE_VERSION 2 +#if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2 +# include <gnu-versions.h> +# if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION +# define ELIDE_CODE +# endif +#endif + +#ifndef ELIDE_CODE + + +/* This needs to come after some library #include + to get __GNU_LIBRARY__ defined. */ +#ifdef __GNU_LIBRARY__ +/* Don't include stdlib.h for non-GNU C libraries because some of them + contain conflicting prototypes for getopt. */ +# include <stdlib.h> +# include <unistd.h> +#endif /* GNU C library. */ + +#ifdef VMS +# include <unixlib.h> +# if HAVE_STRING_H - 0 +# include <string.h> +# endif +#endif + +#ifndef _ +/* This is for other GNU distributions with internationalized messages. + When compiling libc, the _ macro is predefined. */ +# ifdef HAVE_LIBINTL_H +# include <libintl.h> +# define _(msgid) gettext (msgid) +# else +# define _(msgid) (msgid) +# endif +#endif + +/* This version of `getopt' appears to the caller like standard Unix `getopt' + but it behaves differently for the user, since it allows the user + to intersperse the options with the other arguments. + + As `getopt' works, it permutes the elements of ARGV so that, + when it is done, all the options precede everything else. Thus + all application programs are extended to handle flexible argument order. + + Setting the environment variable POSIXLY_CORRECT disables permutation. + Then the behavior is completely standard. + + GNU application programs can use a third alternative mode in which + they can distinguish the relative order of options and other arguments. */ + +#include "getopt.h" + +/* For communication from `getopt' to the caller. + When `getopt' finds an option that takes an argument, + the argument value is returned here. + Also, when `ordering' is RETURN_IN_ORDER, + each non-option ARGV-element is returned here. */ + +char *optarg; + +/* Index in ARGV of the next element to be scanned. + This is used for communication to and from the caller + and for communication between successive calls to `getopt'. + + On entry to `getopt', zero means this is the first call; initialize. + + When `getopt' returns -1, this is the index of the first of the + non-option elements that the caller should itself scan. + + Otherwise, `optind' communicates from one call to the next + how much of ARGV has been scanned so far. */ + +/* 1003.2 says this must be 1 before any call. */ +int optind = 1; + +/* Formerly, initialization of getopt depended on optind==0, which + causes problems with re-calling getopt as programs generally don't + know that. */ + +int __getopt_initialized; + +/* The next char to be scanned in the option-element + in which the last option character we returned was found. + This allows us to pick up the scan where we left off. + + If this is zero, or a null string, it means resume the scan + by advancing to the next ARGV-element. */ + +static char *nextchar; + +/* Callers store zero here to inhibit the error message + for unrecognized options. */ + +int opterr = 1; + +/* Set to an option character which was unrecognized. + This must be initialized on some systems to avoid linking in the + system's own getopt implementation. */ + +int optopt = '?'; + +/* Describe how to deal with options that follow non-option ARGV-elements. + + If the caller did not specify anything, + the default is REQUIRE_ORDER if the environment variable + POSIXLY_CORRECT is defined, PERMUTE otherwise. + + REQUIRE_ORDER means don't recognize them as options; + stop option processing when the first non-option is seen. + This is what Unix does. + This mode of operation is selected by either setting the environment + variable POSIXLY_CORRECT, or using `+' as the first character + of the list of option characters. + + PERMUTE is the default. We permute the contents of ARGV as we scan, + so that eventually all the non-options are at the end. This allows options + to be given in any order, even with programs that were not written to + expect this. + + RETURN_IN_ORDER is an option available to programs that were written + to expect options and other ARGV-elements in any order and that care about + the ordering of the two. We describe each non-option ARGV-element + as if it were the argument of an option with character code 1. + Using `-' as the first character of the list of option characters + selects this mode of operation. + + The special argument `--' forces an end of option-scanning regardless + of the value of `ordering'. In the case of RETURN_IN_ORDER, only + `--' can cause `getopt' to return -1 with `optind' != ARGC. */ + +static enum +{ + REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER +} ordering; + +/* Value of POSIXLY_CORRECT environment variable. */ +static char *posixly_correct; + +#ifdef __GNU_LIBRARY__ +/* We want to avoid inclusion of string.h with non-GNU libraries + because there are many ways it can cause trouble. + On some systems, it contains special magic macros that don't work + in GCC. */ +# include <string.h> +# define my_index strchr +#else + +# if HAVE_STRING_H +# include <string.h> +# else +# include <strings.h> +# endif + +/* Avoid depending on library functions or files + whose names are inconsistent. */ + +#ifndef getenv +extern char *getenv (); +#endif + +static char * +my_index (str, chr) + const char *str; + int chr; +{ + while (*str) + { + if (*str == chr) + return (char *) str; + str++; + } + return 0; +} + +/* If using GCC, we can safely declare strlen this way. + If not using GCC, it is ok not to declare it. */ +#ifdef __GNUC__ +/* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h. + That was relevant to code that was here before. */ +# if (!defined __STDC__ || !__STDC__) && !defined strlen +/* gcc with -traditional declares the built-in strlen to return int, + and has done so at least since version 2.4.5. -- rms. */ +extern int strlen (const char *); +# endif /* not __STDC__ */ +#endif /* __GNUC__ */ + +#endif /* not __GNU_LIBRARY__ */ + +/* Handle permutation of arguments. */ + +/* Describe the part of ARGV that contains non-options that have + been skipped. `first_nonopt' is the index in ARGV of the first of them; + `last_nonopt' is the index after the last of them. */ + +static int first_nonopt; +static int last_nonopt; + +#ifdef _LIBC +/* Bash 2.0 gives us an environment variable containing flags + indicating ARGV elements that should not be considered arguments. */ + +/* Defined in getopt_init.c */ +extern char *__getopt_nonoption_flags; + +static int nonoption_flags_max_len; +static int nonoption_flags_len; + +static int original_argc; +static char *const *original_argv; + +/* Make sure the environment variable bash 2.0 puts in the environment + is valid for the getopt call we must make sure that the ARGV passed + to getopt is that one passed to the process. */ +static void +__attribute__ ((unused)) +store_args_and_env (int argc, char *const *argv) +{ + /* XXX This is no good solution. We should rather copy the args so + that we can compare them later. But we must not use malloc(3). */ + original_argc = argc; + original_argv = argv; +} +# ifdef text_set_element +text_set_element (__libc_subinit, store_args_and_env); +# endif /* text_set_element */ + +# define SWAP_FLAGS(ch1, ch2) \ + if (nonoption_flags_len > 0) \ + { \ + char __tmp = __getopt_nonoption_flags[ch1]; \ + __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2]; \ + __getopt_nonoption_flags[ch2] = __tmp; \ + } +#else /* !_LIBC */ +# define SWAP_FLAGS(ch1, ch2) +#endif /* _LIBC */ + +/* Exchange two adjacent subsequences of ARGV. + One subsequence is elements [first_nonopt,last_nonopt) + which contains all the non-options that have been skipped so far. + The other is elements [last_nonopt,optind), which contains all + the options processed since those non-options were skipped. + + `first_nonopt' and `last_nonopt' are relocated so that they describe + the new indices of the non-options in ARGV after they are moved. */ + +#if defined __STDC__ && __STDC__ +static void exchange (char **); +#endif + +static void +exchange (argv) + char **argv; +{ + int bottom = first_nonopt; + int middle = last_nonopt; + int top = optind; + char *tem; + + /* Exchange the shorter segment with the far end of the longer segment. + That puts the shorter segment into the right place. + It leaves the longer segment in the right place overall, + but it consists of two parts that need to be swapped next. */ + +#ifdef _LIBC + /* First make sure the handling of the `__getopt_nonoption_flags' + string can work normally. Our top argument must be in the range + of the string. */ + if (nonoption_flags_len > 0 && top >= nonoption_flags_max_len) + { + /* We must extend the array. The user plays games with us and + presents new arguments. */ + char *new_str = malloc (top + 1); + if (new_str == NULL) + nonoption_flags_len = nonoption_flags_max_len = 0; + else + { + memset (__mempcpy (new_str, __getopt_nonoption_flags, + nonoption_flags_max_len), + '\0', top + 1 - nonoption_flags_max_len); + nonoption_flags_max_len = top + 1; + __getopt_nonoption_flags = new_str; + } + } +#endif + + while (top > middle && middle > bottom) + { + if (top - middle > middle - bottom) + { + /* Bottom segment is the short one. */ + int len = middle - bottom; + register int i; + + /* Swap it with the top part of the top segment. */ + for (i = 0; i < len; i++) + { + tem = argv[bottom + i]; + argv[bottom + i] = argv[top - (middle - bottom) + i]; + argv[top - (middle - bottom) + i] = tem; + SWAP_FLAGS (bottom + i, top - (middle - bottom) + i); + } + /* Exclude the moved bottom segment from further swapping. */ + top -= len; + } + else + { + /* Top segment is the short one. */ + int len = top - middle; + register int i; + + /* Swap it with the bottom part of the bottom segment. */ + for (i = 0; i < len; i++) + { + tem = argv[bottom + i]; + argv[bottom + i] = argv[middle + i]; + argv[middle + i] = tem; + SWAP_FLAGS (bottom + i, middle + i); + } + /* Exclude the moved top segment from further swapping. */ + bottom += len; + } + } + + /* Update records for the slots the non-options now occupy. */ + + first_nonopt += (optind - last_nonopt); + last_nonopt = optind; +} + +/* Initialize the internal data when the first call is made. */ + +#if defined __STDC__ && __STDC__ +static const char *_getopt_initialize (int, char *const *, const char *); +#endif +static const char * +_getopt_initialize (argc, argv, optstring) + int argc; + char *const *argv; + const char *optstring; +{ + /* Start processing options with ARGV-element 1 (since ARGV-element 0 + is the program name); the sequence of previously skipped + non-option ARGV-elements is empty. */ + + first_nonopt = last_nonopt = optind; + + nextchar = NULL; + + posixly_correct = getenv ("POSIXLY_CORRECT"); + + /* Determine how to handle the ordering of options and nonoptions. */ + + if (optstring[0] == '-') + { + ordering = RETURN_IN_ORDER; + ++optstring; + } + else if (optstring[0] == '+') + { + ordering = REQUIRE_ORDER; + ++optstring; + } + else if (posixly_correct != NULL) + ordering = REQUIRE_ORDER; + else + ordering = PERMUTE; + +#ifdef _LIBC + if (posixly_correct == NULL + && argc == original_argc && argv == original_argv) + { + if (nonoption_flags_max_len == 0) + { + if (__getopt_nonoption_flags == NULL + || __getopt_nonoption_flags[0] == '\0') + nonoption_flags_max_len = -1; + else + { + const char *orig_str = __getopt_nonoption_flags; + int len = nonoption_flags_max_len = strlen (orig_str); + if (nonoption_flags_max_len < argc) + nonoption_flags_max_len = argc; + __getopt_nonoption_flags = + (char *) malloc (nonoption_flags_max_len); + if (__getopt_nonoption_flags == NULL) + nonoption_flags_max_len = -1; + else + memset (__mempcpy (__getopt_nonoption_flags, orig_str, len), + '\0', nonoption_flags_max_len - len); + } + } + nonoption_flags_len = nonoption_flags_max_len; + } + else + nonoption_flags_len = 0; +#endif + + return optstring; +} + +/* Scan elements of ARGV (whose length is ARGC) for option characters + given in OPTSTRING. + + If an element of ARGV starts with '-', and is not exactly "-" or "--", + then it is an option element. The characters of this element + (aside from the initial '-') are option characters. If `getopt' + is called repeatedly, it returns successively each of the option characters + from each of the option elements. + + If `getopt' finds another option character, it returns that character, + updating `optind' and `nextchar' so that the next call to `getopt' can + resume the scan with the following option character or ARGV-element. + + If there are no more option characters, `getopt' returns -1. + Then `optind' is the index in ARGV of the first ARGV-element + that is not an option. (The ARGV-elements have been permuted + so that those that are not options now come last.) + + OPTSTRING is a string containing the legitimate option characters. + If an option character is seen that is not listed in OPTSTRING, + return '?' after printing an error message. If you set `opterr' to + zero, the error message is suppressed but we still return '?'. + + If a char in OPTSTRING is followed by a colon, that means it wants an arg, + so the following text in the same ARGV-element, or the text of the following + ARGV-element, is returned in `optarg'. Two colons mean an option that + wants an optional arg; if there is text in the current ARGV-element, + it is returned in `optarg', otherwise `optarg' is set to zero. + + If OPTSTRING starts with `-' or `+', it requests different methods of + handling the non-option ARGV-elements. + See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above. + + Long-named options begin with `--' instead of `-'. + Their names may be abbreviated as long as the abbreviation is unique + or is an exact match for some defined option. If they have an + argument, it follows the option name in the same ARGV-element, separated + from the option name by a `=', or else the in next ARGV-element. + When `getopt' finds a long-named option, it returns 0 if that option's + `flag' field is nonzero, the value of the option's `val' field + if the `flag' field is zero. + + The elements of ARGV aren't really const, because we permute them. + But we pretend they're const in the prototype to be compatible + with other systems. + + LONGOPTS is a vector of `struct option' terminated by an + element containing a name which is zero. + + LONGIND returns the index in LONGOPT of the long-named option found. + It is only valid when a long-named option has been found by the most + recent call. + + If LONG_ONLY is nonzero, '-' as well as '--' can introduce + long-named options. */ + +int +_getopt_internal (argc, argv, optstring, longopts, longind, long_only) + int argc; + char *const *argv; + const char *optstring; + const struct option *longopts; + int *longind; + int long_only; +{ + optarg = NULL; + + if (optind == 0 || !__getopt_initialized) + { + if (optind == 0) + optind = 1; /* Don't scan ARGV[0], the program name. */ + optstring = _getopt_initialize (argc, argv, optstring); + __getopt_initialized = 1; + } + + /* Test whether ARGV[optind] points to a non-option argument. + Either it does not have option syntax, or there is an environment flag + from the shell indicating it is not an option. The later information + is only used when the used in the GNU libc. */ +#ifdef _LIBC +# define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0' \ + || (optind < nonoption_flags_len \ + && __getopt_nonoption_flags[optind] == '1')) +#else +# define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0') +#endif + + if (nextchar == NULL || *nextchar == '\0') + { + /* Advance to the next ARGV-element. */ + + /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been + moved back by the user (who may also have changed the arguments). */ + if (last_nonopt > optind) + last_nonopt = optind; + if (first_nonopt > optind) + first_nonopt = optind; + + if (ordering == PERMUTE) + { + /* If we have just processed some options following some non-options, + exchange them so that the options come first. */ + + if (first_nonopt != last_nonopt && last_nonopt != optind) + exchange ((char **) argv); + else if (last_nonopt != optind) + first_nonopt = optind; + + /* Skip any additional non-options + and extend the range of non-options previously skipped. */ + + while (optind < argc && NONOPTION_P) + optind++; + last_nonopt = optind; + } + + /* The special ARGV-element `--' means premature end of options. + Skip it like a null option, + then exchange with previous non-options as if it were an option, + then skip everything else like a non-option. */ + + if (optind != argc && !strcmp (argv[optind], "--")) + { + optind++; + + if (first_nonopt != last_nonopt && last_nonopt != optind) + exchange ((char **) argv); + else if (first_nonopt == last_nonopt) + first_nonopt = optind; + last_nonopt = argc; + + optind = argc; + } + + /* If we have done all the ARGV-elements, stop the scan + and back over any non-options that we skipped and permuted. */ + + if (optind == argc) + { + /* Set the next-arg-index to point at the non-options + that we previously skipped, so the caller will digest them. */ + if (first_nonopt != last_nonopt) + optind = first_nonopt; + return -1; + } + + /* If we have come to a non-option and did not permute it, + either stop the scan or describe it to the caller and pass it by. */ + + if (NONOPTION_P) + { + if (ordering == REQUIRE_ORDER) + return -1; + optarg = argv[optind++]; + return 1; + } + + /* We have found another option-ARGV-element. + Skip the initial punctuation. */ + + nextchar = (argv[optind] + 1 + + (longopts != NULL && argv[optind][1] == '-')); + } + + /* Decode the current option-ARGV-element. */ + + /* Check whether the ARGV-element is a long option. + + If long_only and the ARGV-element has the form "-f", where f is + a valid short option, don't consider it an abbreviated form of + a long option that starts with f. Otherwise there would be no + way to give the -f short option. + + On the other hand, if there's a long option "fubar" and + the ARGV-element is "-fu", do consider that an abbreviation of + the long option, just like "--fu", and not "-f" with arg "u". + + This distinction seems to be the most useful approach. */ + + if (longopts != NULL + && (argv[optind][1] == '-' + || (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1]))))) + { + char *nameend; + const struct option *p; + const struct option *pfound = NULL; + int exact = 0; + int ambig = 0; + int indfound = -1; + int option_index; + + for (nameend = nextchar; *nameend && *nameend != '='; nameend++) + /* Do nothing. */ ; + + /* Test all long options for either exact match + or abbreviated matches. */ + for (p = longopts, option_index = 0; p->name; p++, option_index++) + if (!strncmp (p->name, nextchar, nameend - nextchar)) + { + if ((unsigned int) (nameend - nextchar) + == (unsigned int) strlen (p->name)) + { + /* Exact match found. */ + pfound = p; + indfound = option_index; + exact = 1; + break; + } + else if (pfound == NULL) + { + /* First nonexact match found. */ + pfound = p; + indfound = option_index; + } + else + /* Second or later nonexact match found. */ + ambig = 1; + } + + if (ambig && !exact) + { + if (opterr) + fprintf (stderr, _("%s: option `%s' is ambiguous\n"), + argv[0], argv[optind]); + nextchar += strlen (nextchar); + optind++; + optopt = 0; + return '?'; + } + + if (pfound != NULL) + { + option_index = indfound; + optind++; + if (*nameend) + { + /* Don't test has_arg with >, because some C compilers don't + allow it to be used on enums. */ + if (pfound->has_arg) + optarg = nameend + 1; + else + { + if (opterr) + { + if (argv[optind - 1][1] == '-') + /* --option */ + fprintf (stderr, + _("%s: option `--%s' doesn't allow an argument\n"), + argv[0], pfound->name); + else + /* +option or -option */ + fprintf (stderr, + _("%s: option `%c%s' doesn't allow an argument\n"), + argv[0], argv[optind - 1][0], pfound->name); + } + + nextchar += strlen (nextchar); + + optopt = pfound->val; + return '?'; + } + } + else if (pfound->has_arg == 1) + { + if (optind < argc) + optarg = argv[optind++]; + else + { + if (opterr) + fprintf (stderr, + _("%s: option `%s' requires an argument\n"), + argv[0], argv[optind - 1]); + nextchar += strlen (nextchar); + optopt = pfound->val; + return optstring[0] == ':' ? ':' : '?'; + } + } + nextchar += strlen (nextchar); + if (longind != NULL) + *longind = option_index; + if (pfound->flag) + { + *(pfound->flag) = pfound->val; + return 0; + } + return pfound->val; + } + + /* Can't find it as a long option. If this is not getopt_long_only, + or the option starts with '--' or is not a valid short + option, then it's an error. + Otherwise interpret it as a short option. */ + if (!long_only || argv[optind][1] == '-' + || my_index (optstring, *nextchar) == NULL) + { + if (opterr) + { + if (argv[optind][1] == '-') + /* --option */ + fprintf (stderr, _("%s: unrecognized option `--%s'\n"), + argv[0], nextchar); + else + /* +option or -option */ + fprintf (stderr, _("%s: unrecognized option `%c%s'\n"), + argv[0], argv[optind][0], nextchar); + } + nextchar = (char *) ""; + optind++; + optopt = 0; + return '?'; + } + } + + /* Look at and handle the next short option-character. */ + + { + char c = *nextchar++; + char *temp = my_index (optstring, c); + + /* Increment `optind' when we start to process its last character. */ + if (*nextchar == '\0') + ++optind; + + if (temp == NULL || c == ':') + { + if (opterr) + { + if (posixly_correct) + /* 1003.2 specifies the format of this message. */ + fprintf (stderr, _("%s: illegal option -- %c\n"), + argv[0], c); + else + fprintf (stderr, _("%s: invalid option -- %c\n"), + argv[0], c); + } + optopt = c; + return '?'; + } + /* Convenience. Treat POSIX -W foo same as long option --foo */ + if (temp[0] == 'W' && temp[1] == ';') + { + char *nameend; + const struct option *p; + const struct option *pfound = NULL; + int exact = 0; + int ambig = 0; + int indfound = 0; + int option_index; + + /* This is an option that requires an argument. */ + if (*nextchar != '\0') + { + optarg = nextchar; + /* If we end this ARGV-element by taking the rest as an arg, + we must advance to the next element now. */ + optind++; + } + else if (optind == argc) + { + if (opterr) + { + /* 1003.2 specifies the format of this message. */ + fprintf (stderr, _("%s: option requires an argument -- %c\n"), + argv[0], c); + } + optopt = c; + if (optstring[0] == ':') + c = ':'; + else + c = '?'; + return c; + } + else + /* We already incremented `optind' once; + increment it again when taking next ARGV-elt as argument. */ + optarg = argv[optind++]; + + /* optarg is now the argument, see if it's in the + table of longopts. */ + + for (nextchar = nameend = optarg; *nameend && *nameend != '='; nameend++) + /* Do nothing. */ ; + + /* Test all long options for either exact match + or abbreviated matches. */ + for (p = longopts, option_index = 0; p->name; p++, option_index++) + if (!strncmp (p->name, nextchar, nameend - nextchar)) + { + if ((unsigned int) (nameend - nextchar) == strlen (p->name)) + { + /* Exact match found. */ + pfound = p; + indfound = option_index; + exact = 1; + break; + } + else if (pfound == NULL) + { + /* First nonexact match found. */ + pfound = p; + indfound = option_index; + } + else + /* Second or later nonexact match found. */ + ambig = 1; + } + if (ambig && !exact) + { + if (opterr) + fprintf (stderr, _("%s: option `-W %s' is ambiguous\n"), + argv[0], argv[optind]); + nextchar += strlen (nextchar); + optind++; + return '?'; + } + if (pfound != NULL) + { + option_index = indfound; + if (*nameend) + { + /* Don't test has_arg with >, because some C compilers don't + allow it to be used on enums. */ + if (pfound->has_arg) + optarg = nameend + 1; + else + { + if (opterr) + fprintf (stderr, _("\ +%s: option `-W %s' doesn't allow an argument\n"), + argv[0], pfound->name); + + nextchar += strlen (nextchar); + return '?'; + } + } + else if (pfound->has_arg == 1) + { + if (optind < argc) + optarg = argv[optind++]; + else + { + if (opterr) + fprintf (stderr, + _("%s: option `%s' requires an argument\n"), + argv[0], argv[optind - 1]); + nextchar += strlen (nextchar); + return optstring[0] == ':' ? ':' : '?'; + } + } + nextchar += strlen (nextchar); + if (longind != NULL) + *longind = option_index; + if (pfound->flag) + { + *(pfound->flag) = pfound->val; + return 0; + } + return pfound->val; + } + nextchar = NULL; + return 'W'; /* Let the application handle it. */ + } + if (temp[1] == ':') + { + if (temp[2] == ':') + { + /* This is an option that accepts an argument optionally. */ + if (*nextchar != '\0') + { + optarg = nextchar; + optind++; + } + else + optarg = NULL; + nextchar = NULL; + } + else + { + /* This is an option that requires an argument. */ + if (*nextchar != '\0') + { + optarg = nextchar; + /* If we end this ARGV-element by taking the rest as an arg, + we must advance to the next element now. */ + optind++; + } + else if (optind == argc) + { + if (opterr) + { + /* 1003.2 specifies the format of this message. */ + fprintf (stderr, + _("%s: option requires an argument -- %c\n"), + argv[0], c); + } + optopt = c; + if (optstring[0] == ':') + c = ':'; + else + c = '?'; + } + else + /* We already incremented `optind' once; + increment it again when taking next ARGV-elt as argument. */ + optarg = argv[optind++]; + nextchar = NULL; + } + } + return c; + } +} + +int +getopt (argc, argv, optstring) + int argc; + char *const *argv; + const char *optstring; +{ + return _getopt_internal (argc, argv, optstring, + (const struct option *) 0, + (int *) 0, + 0); +} + +#endif /* Not ELIDE_CODE. */ + +#ifdef TEST + +/* Compile with -DTEST to make an executable for use in testing + the above definition of `getopt'. */ + +int +main (argc, argv) + int argc; + char **argv; +{ + int c; + int digit_optind = 0; + + while (1) + { + int this_option_optind = optind ? optind : 1; + + c = getopt (argc, argv, "abc:d:0123456789"); + if (c == -1) + break; + + switch (c) + { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + if (digit_optind != 0 && digit_optind != this_option_optind) + printf ("digits occur in two different argv-elements.\n"); + digit_optind = this_option_optind; + printf ("option %c\n", c); + break; + + case 'a': + printf ("option a\n"); + break; + + case 'b': + printf ("option b\n"); + break; + + case 'c': + printf ("option c with value `%s'\n", optarg); + break; + + case '?': + break; + + default: + printf ("?? getopt returned character code 0%o ??\n", c); + } + } + + if (optind < argc) + { + printf ("non-option ARGV-elements: "); + while (optind < argc) + printf ("%s ", argv[optind++]); + printf ("\n"); + } + + exit (0); +} + +#endif /* TEST */ diff --git a/debian/transcode/transcode-1.1.7/libtc/getopt.h b/debian/transcode/transcode-1.1.7/libtc/getopt.h new file mode 100644 index 00000000..a1b8dd66 --- /dev/null +++ b/debian/transcode/transcode-1.1.7/libtc/getopt.h @@ -0,0 +1,180 @@ +/* Declarations for getopt. + Copyright (C) 1989-1994, 1996-1999, 2001 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C 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 2.1 of the License, or (at your option) any later version. + + The GNU C 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 the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#ifndef _GETOPT_H + +#ifndef __need_getopt +# define _GETOPT_H 1 +#endif + +/* If __GNU_LIBRARY__ is not already defined, either we are being used + standalone, or this is the first header included in the source file. + If we are being used with glibc, we need to include <features.h>, but + that does not exist if we are standalone. So: if __GNU_LIBRARY__ is + not defined, include <ctype.h>, which will pull in <features.h> for us + if it's from glibc. (Why ctype.h? It's guaranteed to exist and it + doesn't flood the namespace with stuff the way some other headers do.) */ +#if !defined __GNU_LIBRARY__ +# include <ctype.h> +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* For communication from `getopt' to the caller. + When `getopt' finds an option that takes an argument, + the argument value is returned here. + Also, when `ordering' is RETURN_IN_ORDER, + each non-option ARGV-element is returned here. */ + +extern char *optarg; + +/* Index in ARGV of the next element to be scanned. + This is used for communication to and from the caller + and for communication between successive calls to `getopt'. + + On entry to `getopt', zero means this is the first call; initialize. + + When `getopt' returns -1, this is the index of the first of the + non-option elements that the caller should itself scan. + + Otherwise, `optind' communicates from one call to the next + how much of ARGV has been scanned so far. */ + +extern int optind; + +/* Callers store zero here to inhibit the error message `getopt' prints + for unrecognized options. */ + +extern int opterr; + +/* Set to an option character which was unrecognized. */ + +extern int optopt; + +#ifndef __need_getopt +/* Describe the long-named options requested by the application. + The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector + of `struct option' terminated by an element containing a name which is + zero. + + The field `has_arg' is: + no_argument (or 0) if the option does not take an argument, + required_argument (or 1) if the option requires an argument, + optional_argument (or 2) if the option takes an optional argument. + + If the field `flag' is not NULL, it points to a variable that is set + to the value given in the field `val' when the option is found, but + left unchanged if the option is not found. + + To have a long-named option do something other than set an `int' to + a compiled-in constant, such as set a value from `optarg', set the + option's `flag' field to zero and its `val' field to a nonzero + value (the equivalent single-letter option character, if there is + one). For long options that have a zero `flag' field, `getopt' + returns the contents of the `val' field. */ + +struct option +{ +# if (defined __STDC__ && __STDC__) || defined __cplusplus + const char *name; +# else + char *name; +# endif + /* has_arg can't be an enum because some compilers complain about + type mismatches in all the code that assumes it is an int. */ + int has_arg; + int *flag; + int val; +}; + +/* Names for the values of the `has_arg' field of `struct option'. */ + +# define no_argument 0 +# define required_argument 1 +# define optional_argument 2 +#endif /* need getopt */ + + +/* Get definitions and prototypes for functions to process the + arguments in ARGV (ARGC of them, minus the program name) for + options given in OPTS. + + Return the option character from OPTS just read. Return -1 when + there are no more options. For unrecognized options, or options + missing arguments, `optopt' is set to the option letter, and '?' is + returned. + + The OPTS string is a list of characters which are recognized option + letters, optionally followed by colons, specifying that that letter + takes an argument, to be placed in `optarg'. + + If a letter in OPTS is followed by two colons, its argument is + optional. This behavior is specific to the GNU `getopt'. + + The argument `--' causes premature termination of argument + scanning, explicitly telling `getopt' that there are no more + options. + + If OPTS begins with `--', then non-option arguments are treated as + arguments to the option '\0'. This behavior is specific to the GNU + `getopt'. */ + +#if (defined __STDC__ && __STDC__) || defined __cplusplus +# ifdef __GNU_LIBRARY__ +/* Many other libraries have conflicting prototypes for getopt, with + differences in the consts, in stdlib.h. To avoid compilation + errors, only prototype getopt for the GNU C library. */ +extern int getopt (int __argc, char *const *__argv, const char *__shortopts); +# else /* not __GNU_LIBRARY__ */ +extern int getopt (); +# endif /* __GNU_LIBRARY__ */ + +# ifndef __need_getopt +extern int getopt_long (int __argc, char *const *__argv, const char *__shortopts, + const struct option *__longopts, int *__longind); +extern int getopt_long_only (int __argc, char *const *__argv, + const char *__shortopts, + const struct option *__longopts, int *__longind); + +/* Internal only. Users should not call this directly. */ +extern int _getopt_internal (int __argc, char *const *__argv, + const char *__shortopts, + const struct option *__longopts, int *__longind, + int __long_only); +# endif +#else /* not __STDC__ */ +extern int getopt (); +# ifndef __need_getopt +extern int getopt_long (); +extern int getopt_long_only (); + +extern int _getopt_internal (); +# endif +#endif /* __STDC__ */ + +#ifdef __cplusplus +} +#endif + +/* Make sure we later can get all the definitions and declarations. */ +#undef __need_getopt + +#endif /* getopt.h */ diff --git a/debian/transcode/transcode-1.1.7/libtc/getopt1.c b/debian/transcode/transcode-1.1.7/libtc/getopt1.c new file mode 100644 index 00000000..22a7efbd --- /dev/null +++ b/debian/transcode/transcode-1.1.7/libtc/getopt1.c @@ -0,0 +1,188 @@ +/* getopt_long and getopt_long_only entry points for GNU getopt. + Copyright (C) 1987,88,89,90,91,92,93,94,96,97,98 + Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C 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 2.1 of the License, or (at your option) any later version. + + The GNU C 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 the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include "getopt.h" + +#if !defined __STDC__ || !__STDC__ +/* This is a separate conditional since some stdc systems + reject `defined (const)'. */ +#ifndef const +#define const +#endif +#endif + +#include <stdio.h> + +/* Comment out all this code if we are using the GNU C Library, and are not + actually compiling the library itself. This code is part of the GNU C + Library, but also included in many other GNU distributions. Compiling + and linking in this code is a waste when using the GNU C library + (especially if it is a shared library). Rather than having every GNU + program understand `configure --with-gnu-libc' and omit the object files, + it is simpler to just do this in the source for each such file. */ + +#define GETOPT_INTERFACE_VERSION 2 +#if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2 +#include <gnu-versions.h> +#if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION +#define ELIDE_CODE +#endif +#endif + +#ifndef ELIDE_CODE + + +/* This needs to come after some library #include + to get __GNU_LIBRARY__ defined. */ +#ifdef __GNU_LIBRARY__ +#include <stdlib.h> +#endif + +#ifndef NULL +#define NULL 0 +#endif + +int +getopt_long (argc, argv, options, long_options, opt_index) + int argc; + char *const *argv; + const char *options; + const struct option *long_options; + int *opt_index; +{ + return _getopt_internal (argc, argv, options, long_options, opt_index, 0); +} + +/* Like getopt_long, but '-' as well as '--' can indicate a long option. + If an option that starts with '-' (not '--') doesn't match a long option, + but does match a short option, it is parsed as a short option + instead. */ + +int +getopt_long_only (argc, argv, options, long_options, opt_index) + int argc; + char *const *argv; + const char *options; + const struct option *long_options; + int *opt_index; +{ + return _getopt_internal (argc, argv, options, long_options, opt_index, 1); +} + + +#endif /* Not ELIDE_CODE. */ + +#ifdef TEST + +#include <stdio.h> + +int +main (argc, argv) + int argc; + char **argv; +{ + int c; + int digit_optind = 0; + + while (1) + { + int this_option_optind = optind ? optind : 1; + int option_index = 0; + static struct option long_options[] = + { + {"add", 1, 0, 0}, + {"append", 0, 0, 0}, + {"delete", 1, 0, 0}, + {"verbose", 0, 0, 0}, + {"create", 0, 0, 0}, + {"file", 1, 0, 0}, + {0, 0, 0, 0} + }; + + c = getopt_long (argc, argv, "abc:d:0123456789", + long_options, &option_index); + if (c == -1) + break; + + switch (c) + { + case 0: + printf ("option %s", long_options[option_index].name); + if (optarg) + printf (" with arg %s", optarg); + printf ("\n"); + break; + + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + if (digit_optind != 0 && digit_optind != this_option_optind) + printf ("digits occur in two different argv-elements.\n"); + digit_optind = this_option_optind; + printf ("option %c\n", c); + break; + + case 'a': + printf ("option a\n"); + break; + + case 'b': + printf ("option b\n"); + break; + + case 'c': + printf ("option c with value `%s'\n", optarg); + break; + + case 'd': + printf ("option d with value `%s'\n", optarg); + break; + + case '?': + break; + + default: + printf ("?? getopt returned character code 0%o ??\n", c); + } + } + + if (optind < argc) + { + printf ("non-option ARGV-elements: "); + while (optind < argc) + printf ("%s ", argv[optind++]); + printf ("\n"); + } + + exit (0); +} + +#endif /* TEST */ diff --git a/debian/transcode/transcode-1.1.7/libtc/iodir.c b/debian/transcode/transcode-1.1.7/libtc/iodir.c new file mode 100644 index 00000000..e11e0a06 --- /dev/null +++ b/debian/transcode/transcode-1.1.7/libtc/iodir.c @@ -0,0 +1,233 @@ +/* + * iodir.c + * + * Copyright (C) Thomas Oestreich - May 2002 + * + * This file is part of transcode, a video stream processing tool + * + * transcode 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, or (at your option) + * any later version. + * + * transcode is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Make; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include "libtc.h" +#include "iodir.h" +#include <stdlib.h> +#include <string.h> + +#ifdef OS_BSD +typedef off_t off64_t; +#define lseek64 lseek +#endif + +/* get the next valid directory entry */ +static int tc_dirlist_next(TCDirList *tcdir) +{ + struct dirent *dent = NULL; + int have_file = 0; + + if (tcdir == NULL) { + return -1; + } + + do { + dent = readdir(tcdir->dir); + if (dent == NULL) { + break; /* all entries in dirlist have been processed */ + } + + if ((strncmp(dent->d_name, ".", 1) != 0) + && (strcmp(dent->d_name, "..") != 0)) { + /* discard special files */ + have_file = 1; + } + + } while (!have_file); + + if (have_file) { + tc_snprintf(tcdir->filename, sizeof(tcdir->filename), + "%s%s%s", tcdir->dir_name, tcdir->path_sep, + dent->d_name); + return 0; + } + return 1; +} + +/* qsort helper */ +static int compare_name(const void *file1_ptr, const void *file2_ptr) +{ + return strcoll(*(const char **)file1_ptr, *(const char **)file2_ptr); +} + +static int tc_dirlist_sortbuf(TCDirList *tcdir) +{ + int n = 0; + + if (tcdir == NULL) { + return -1; + } + + tcdir->entries = tc_malloc(tcdir->nfiles * sizeof(char *)); + if (tcdir->entries == NULL) { + return -1; + } + + while (tc_dirlist_next(tcdir) == 0) { + tcdir->entries[n] = tc_strdup(tcdir->filename); + if (tcdir->entries[n] == NULL) { + tc_log_warn(__FILE__, "can't memorize dirlist entry " + "for '%s'\n", tcdir->filename); + } + n++; + } + + qsort(tcdir->entries, tcdir->nfiles, sizeof(char *), compare_name); + + tcdir->buffered = 1; + tcdir->findex = 0; + + return 0; +} + +static int tc_dirlist_set_path_sep(TCDirList *tcdir) +{ + size_t len = 0; + char end_of_dir; + + len = strlen(tcdir->dir_name); + if (len == 0) { + return -1; + } + + end_of_dir = tcdir->dir_name[len - 1]; + if (end_of_dir == '/') { + tcdir->path_sep = ""; + } else { + tcdir->path_sep = "/"; + } + + return 0; +} + +int tc_dirlist_file_count(TCDirList *tcdir) +{ + if (tcdir == NULL) { + return -1; + } + return tcdir->nfiles; +} + + +int tc_dirlist_open(TCDirList *tcdir, const char *dirname, int sort) +{ + int ret; + + if (tcdir == NULL) { + return -1; + } + + tcdir->filename[0] = '\0'; + tcdir->entries = NULL; + tcdir->nfiles = 0; + tcdir->findex = 0; + tcdir->buffered = 0; + tcdir->dir_name = dirname; + + ret = tc_dirlist_set_path_sep(tcdir); + if (ret != 0) { + return ret; + } + + tcdir->dir = opendir(dirname); + if (tcdir->dir == NULL) { + return -1; + } + + rewinddir(tcdir->dir); + while (tc_dirlist_next(tcdir) == 0) { + tcdir->nfiles++; + } + rewinddir(tcdir->dir); + + if (sort) { + tc_dirlist_sortbuf(tcdir); + } + return 0; +} + +void tc_dirlist_close(TCDirList *tcdir) +{ + if (tcdir != NULL) { + if (tcdir->buffered == 1) { + int i = 0; + for (i = 0; i < tcdir->nfiles; i++) { + if (tcdir->entries[i] != NULL) { + /* should be always true */ + free(tcdir->entries[i]); + tcdir->nfiles--; + } + } + + if (tcdir->entries != NULL) { + /* should be always true */ + free(tcdir->entries); + } + + if (tcdir->nfiles > 0) { + /* should never happen */ + tc_log_warn(__FILE__, "left out %i directory entries", + tcdir->nfiles); + } + } + + if (tcdir->dir != NULL) { + closedir(tcdir->dir); + tcdir->dir = NULL; + } + } +} + +const char *tc_dirlist_scan(TCDirList *tcdir) +{ + const char *ret = NULL; + + if (tcdir == NULL) { + return NULL; + } + + if (tcdir->buffered == 0) { + if (tc_dirlist_next(tcdir) == 0) { + ret = tcdir->filename; + } + } else { + /* buffered */ + if (tcdir->findex < tcdir->nfiles) { + ret = tcdir->entries[tcdir->findex++]; + } + } + + return ret; +} + +/*************************************************************************/ + +/* + * Local variables: + * c-file-style: "stroustrup" + * c-file-offsets: ((case-label . *) (statement-case-intro . *)) + * indent-tabs-mode: nil + * End: + * + * vim: expandtab shiftwidth=4: + */ diff --git a/debian/transcode/transcode-1.1.7/libtc/iodir.h b/debian/transcode/transcode-1.1.7/libtc/iodir.h new file mode 100644 index 00000000..8ae5e8c2 --- /dev/null +++ b/debian/transcode/transcode-1.1.7/libtc/iodir.h @@ -0,0 +1,154 @@ +/* + * iodir.h + * + * Copyright (C) Thomas Oestreich - June 2001 + * Updates: + * Copyright (C) Francesco Romani - November 2005 + * + * This file is part of transcode, a video stream processing tool + * + * transcode 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, or (at your option) + * any later version. + * + * transcode is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Make; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include "config.h" + +#ifndef IODIR_H +#define IODIR_H + +#include <dirent.h> + +typedef struct tcdirlist_ TCDirList; +struct tcdirlist_ { + DIR *dir; /* for internal use */ + + const char *dir_name; /* saved base path */ + const char *path_sep; /* optional *nix path separator */ + + char filename[PATH_MAX + 2]; + /* + * full path of file actually under focus + optional separator + + * final string terminator + */ + char **entries; + /* array of full PATHs of files in scanned dirlist */ + + int nfiles; /* (current) number of files in dirlist */ + int findex; /* index of file under focus */ + int buffered; + /* boolean flag: above array of file in directory is valid? */ +}; + +/* + * tc_dirlist_open: + * initialize a TCDirList descriptor. + * every TCDirList descriptor refers to a specific directory in + * filesystem, and more descriptors can refer to the same directory. + * BIG FAT WARNING: + * all iodir code relies on assumption that target directory + * *WILL NOT CHANGE* when referring descriptor is active. + * + * Parameters: + * tcdir: TCDirList structure (descriptor) to initialize. + * dirname: full path of target directory. + * sort: boolean flag. If is !0, use buffered mode. + * further calls to tc_dirlist_scan will return + * directory entries in lexicographical order. + * otherwise use unbuffered mode. + * Return Value: + * -1 if some parameter is wrong or if target + * directory can't be opened. + * 0 succesfull. + * Side effects: + * none + * Preconditions: + * referred directory *MUST NOT CHANGE* until descriptor + * will be closed via tc_dirlist_close(). + * Postconditions: + * none + */ +int tc_dirlist_open(TCDirList *tcdir, const char *dirname, int sort); + +/* + * tc_dirlist_scan: + * give full path of next entry in target directory. This function + * can operate in two modes, returning the same values to caller + * (if preconditions holds) but in different order. + * The first, standard mode is the so called 'unbuffered' mode. + * In this mode, this function simply scan the target directory, build + * the full path for each entry and return to the caller in filesystem + * order. The other operating mode is the 'buffered' mode, and + * it's triggered using a non-zero value for parameter 'sort' in + * tc_dirlist_open (see above). When in buffered mode, this function + * will return the full path of each entry in target directory in + * lexicogrpaphical order. Otherwise full path is given using + * filesystem order. + * + * Parameters: + * tcdir: TCDirList structure (descriptor) to use. + * Return Value: + * a constant pointer to full path of next entry NULL there are no + * more entries, or if an internal error occurs. + * Side effects: + * in unbuffered mode, target directory will be scanned one time. + * Preconditions: + * referred directory *MUST NOT CHANGE* until descriptor + * will be closed via tc_dirlist_close(). + * 'tcdir' was initialized calling tc_dirlist_open(). + * Postconditions: + * none + */ +const char *tc_dirlist_scan(TCDirList *tcdir); + +/* + * tc_dirlist_close: + * finalize a TCDirList structure (descriptor), freeing all + * acquired resources. + * + * Parameters: + * tcdir: TCDirList structure (descriptor) to close. + * Return Value: + * none + * Side effects: + * none + * Preconditions: + * referred directory *MUST NOT BE CHANGED* until now. + * 'tcdir' was initialized calling tc_dirlist_open() + * Postconditions: + * none + */ +void tc_dirlist_close(TCDirList *tcdir); + +/* + * tc_dirlist_file_count: + * return the actual count of files in target directory. + * + * Parameters: + * tcdir: TCDirList structure (descriptor) to use. + * Return Value: + * actual count of files in target directory + * -1 if 'tcdir' is an invalid descriptor + * Side effects: + * none + * Preconditions: + * referred directory *MUST NOT CHANGE* until descriptor will be closed + * via tc_dirlist_close(). + * 'tcdir' was initialized calling tc_dirlist_open(). + * Postconditions: + * none + */ +int tc_dirlist_file_count(TCDirList *tcdir); + +#endif /* IODIR_H */ diff --git a/debian/transcode/transcode-1.1.7/libtc/libtc.h b/debian/transcode/transcode-1.1.7/libtc/libtc.h new file mode 100644 index 00000000..8e2c6938 --- /dev/null +++ b/debian/transcode/transcode-1.1.7/libtc/libtc.h @@ -0,0 +1,862 @@ +/* + * libtc.h - include file for utilities library for transcode + * + * Copyright (C) Thomas Oestreich - August 2003 + * Copyright (C) Transcode Team - 2005-2010 + * + * This file is part of transcode, a video stream processing tool + * + * transcode 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, or (at your option) + * any later version. + * + * transcode is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Make; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#ifndef LIBTC_H +#define LIBTC_H + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <stdarg.h> +#include <stdlib.h> +#include <stdint.h> +#include <sys/types.h> +#include <sys/param.h> +#include <string.h> +#include <pthread.h> + +#ifndef OS_BSD +# ifdef HAVE_MALLOC_H +# include <malloc.h> +# endif +#endif + +#include "tccodecs.h" +#include "tcformats.h" + +#ifdef __cplusplus +extern "C" { +#endif + +enum { + TC_FALSE, + TC_TRUE +}; + +#define TC_NULL_MATCH -1 + +#define TC_BUF_MAX 1024 +#define TC_BUF_LINE 256 +#define TC_BUF_MIN 128 + +#define TC_MAX(a, b) (((a) > (b)) ?(a) :(b)) +#define TC_MIN(a, b) (((a) < (b)) ?(a) :(b)) +/* clamp x between a and b */ +#define TC_CLAMP(x, a, b) TC_MIN(TC_MAX((a), (x)), (b)) + +/* colors macros */ +#define COL(x) "\033[" #x ";1m" +#define COL_RED COL(31) +#define COL_GREEN COL(32) +#define COL_YELLOW COL(33) +#define COL_BLUE COL(34) +#define COL_WHITE COL(37) +#define COL_GRAY "\033[0m" + +#define TC_LOG_COLOR_ENV_VAR "TRANSCODE_LOG_NO_COLOR" +#define TC_LOG_COLOR_OPTION "--log_no_color" + +/* + * Made to be compatible with + * TC_IMPORT_{OK,ERROR,UNKNOWN} + * TC_EXPORT_{OK,ERROR,UNKNOWN} + * see src/transcode.h + */ +typedef enum { + TC_ERROR = -1, + TC_OK = 0, + TC_INTERRUPT = 1, + TC_UNKNOWN, /* MUST always be the last one */ +} TCReturnCode; + + +typedef enum { + TC_LOG_ERR = 0, /* critical error condition */ + TC_LOG_WARN, /* non-critical error condition */ + TC_LOG_INFO, /* informative highlighted message */ + TC_LOG_MSG, /* regular message */ + + TC_LOG_EXTRA, /* must always be the last */ + /* + * on this special log level is guaranteed that message will be logged + * verbatim: no tag, no colours, anything + */ +} TCLogLevel; + + +/* + * libtc_init: + * tune up some libtc settings. + * You DO NOT always NEED to use this function because libtc has it + * (most of time) sane defaults; just use this function to adapt + * libtc behaviour to some unusual conditions, like if stderr is a file + * and not a terminal. + * If you use this function, you MUST call it BEFORE any other libtc call, + * or you will experience undefined behaviours. + * It's safe to call libtc_setup multiple times BEFORE to call any other + * libtc function. + * + * Parameters: + * flags: flag to tune libtc behaviour (see above) + * Return Value: + * N/A + * Side effects: + * various. See description of flags above. + * Preconditions: + * this function, IF used, MUST be called BEFORE any other libtc function. + */ +void libtc_init(int *argc, char ***argv); + +/* + * tc_log: + * main libtc logging function. Log arbitrary messages according + * to a printf-like format chosen by the caller. + * + * Parameters: + * level: priority of message to log; see TCLogLevel definition + * above. + * tag: header of message, to identify subsystem originating + * the message. It's suggested to use __FILE__ as + * fallback default tag. + * fmt: printf-like format string. You must provide enough + * further arguments to fullfill format string, doing + * otherwise will cause an undefined behaviour, most + * likely a crash. + * Return Value: + * 0 if message succesfully logged. + * -1 if message was truncated. + * (message too large and buffer allocation failed). + * Side effects: + * this function store final message in an intermediate string + * before to log it to destination. If such intermediate string + * is wider than a given amount (TC_BUF_MIN * 2 at moment + * of writing), tc_log needs to dinamically allocate some memory. + * This allocation can fail, and as result log message will be + * truncated to fit in avalaible static buffer. + */ +int tc_log(TCLogLevel level, const char *tag, const char *fmt, ...) +#ifdef HAVE_GCC_ATTRIBUTES +__attribute__((format(printf,3,4))) +#endif +; + +/* + * When to use tc_log*() stuff? + * + * tc_log() family should be used for non-output status messages, like + * the ones coming from the various modules and components of transcode. + * For actual output use printf() (or fprintf(), etc.) as appropriate. + * (yes, this means that transcode prints a lot of status and a very + * few output messages). + */ + +/* compatibility macros */ +#define tc_error(format, args...) do { \ + tc_log(TC_LOG_ERR, PACKAGE, format , ## args); \ + exit(1); \ +} while(0) +#define tc_info(format, args...) \ + tc_log(TC_LOG_INFO, PACKAGE, format , ## args) +#define tc_warn(format, args...) \ + tc_log(TC_LOG_WARN, PACKAGE, format , ## args) + +/* macro goodies */ +#define tc_log_error(tag, format, args...) \ + tc_log(TC_LOG_ERR, tag, format , ## args) +#define tc_log_info(tag, format, args...) \ + tc_log(TC_LOG_INFO, tag, format , ## args) +#define tc_log_warn(tag, format, args...) \ + tc_log(TC_LOG_WARN, tag, format , ## args) +#define tc_log_msg(tag, format, args...) \ + tc_log(TC_LOG_MSG, tag, format , ## args) + +#define tc_log_perror(tag, string) do { \ + const char *__s = (string); /* watch out for side effects */ \ + tc_log_error(tag, "%s%s%s", __s ? __s : "", \ + (__s && *__s) ? ": " : "", strerror(errno)); \ +} while (0) + +/*************************************************************************/ + +/* + * tc_mangle_cmdline: + * parse a command line option array looking for a given option. + * Given option can be short or long but must be given literally. + * So, if you want to mangle "--foobar", give "--foobar" not + * "foobar". Same story for short options "-V": use "-V" not "V". + * If given option isn't found in string option array, do nothing + * and return succesfull (see below). If option is found but + * its argument isn't found, don't mangle string options array + * but return failure. + * If BOTH option and its value is found, store a pointer to + * option value into "optval" parameter and remove both option + * and value from string options array. + * Parameters: + * argc: pointer to number of values present into option string + * array. This parameter must be !NULL and it's updated + * by a succesfull call of this function. + * argv: pointer to array of option string items. This parameter + * must be !NULL and it's updated by a succesfull call of + * this function + * opt: option to look for. + * optval: if !NULL, this function will expect a value for given option; + * if such value is found, `optval' will point to it. + * Return value: + * 1: no option found + * 0: succesfull + * -1: bad parameter(s) (NULL) + * -2: bad usage: expected value for option, but not found, + * Postconditions: + * this function must operate trasparently by always leaving + * argc/argv in an usable and consistent state. + */ +int tc_mangle_cmdline(int *argc, char ***argv, + const char *opt, const char **optval); + +/* + * tc_test_program: + * check if a given program is avalaible in current PATH. + * This function of course needs to read (and copy) the PATH + * environment variable + * + * Parameters: + * name: name of program to look for. + * Return Value: + * 0 if program was found in PATH. + * ENOENT if program was not found in PATH + * value of errno if program was found in PATH but it wasn't accessible + * for some reason. + */ +int tc_test_program(const char *name); + +/* + * Safer string functions from OpenBSD, because these are not in all + * libc implementations. + */ + +#ifndef HAVE_STRLCPY +size_t strlcpy(char *dst, const char *src, size_t size); +#endif + +#ifndef HAVE_STRLCAT +size_t strlcat(char *dst, const char *src, size_t size); +#endif + +/* + * tc_strsplit: + * split a given string into tokens using given separator character. + * Return NULL-terminated array of splitted tokens, and optionally + * return (via a out parameter) size of returned array. + * + * Parameters: + * str: string to split + * sep: separator CHARACTER: cut string when sep is found + * pieces_num: if not NULL, store here the size of returned array + * Return value: + * NULL-terminated array of splitted pieces. + * You must explicitely free this returned array by using tc_strfreev + * (see below) in order to avoid memleaks. + */ +char **tc_strsplit(const char *str, char sep, size_t *pieces_num); + +/* + * tc_strfreev: + * return an array of strings as returned by tc_strsplit + * + * Parameters: + * pieces: return value of tc_strsplit to be freed. + * Return value: + * None. + */ +void tc_strfreev(char **pieces); + +/* + * tc_strstrip: + * remove IN PLACE heading and trailing whitespaces from a given + * C-string. This means that given string will be mangled to + * remove such whitespace while moving pointer to first element + * and terminating '\0'. + * It's safe to supply a NULL string. + * Parameters: + * s: string to strip. + * Return Value: + * None + */ +void tc_strstrip(char *s); + +/* + * tc_test_string: + * check the return value of snprintf, strlcpy, and strlcat. + * If an error is detected, prints reason. + * + * Parameters: + * file: name of source code file on which this function is called + * (this parameter is usually equal to __FILE__). + * line: line of source code file on which this function is called + * (this parameter is usually equal to __LINE__). + * limit: maximum size of char buffer previously used. + * ret: return code of one of above function. + * errnum: error code (this parameter is usually equal to errno) + * Return Value: + * < 0 is an internal error. + * >= limit means characters were truncated. + * 0 if not problems. + * 1 if error. + */ +int tc_test_string(const char *file, int line, int limit, + long ret, int errnum); + + +/* + * These versions of [v]snprintf() return -1 if the string was truncated, + * printing a message to stderr in case of truncation (or other error). + */ +#define tc_vsnprintf(buf,limit,format,args...) \ + _tc_vsnprintf(__FILE__, __LINE__, buf, limit, format , ## args) +#define tc_snprintf(buf,limit,format,args...) \ + _tc_snprintf(__FILE__, __LINE__, buf, limit, format , ## args) + +int _tc_vsnprintf(const char *file, int line, char *buf, size_t limit, + const char *format, va_list args); +int _tc_snprintf(const char *file, int line, char *buf, size_t limit, + const char *format, ...); + +/*************************************************************************/ + +/* + * tc_malloc: just a simple wrapper on libc's malloc(), with emits + * an additional warning, specifying calling context, + * if allocation fails + * tc_zalloc: like tc_malloc, but zeroes all acquired memory before + * returning to the caller (this is quite common in + * transcode codebase) + * tc_realloc: the same thing for realloc() + * tc_free: the companion memory releasing wrapper. + */ +#define tc_malloc(size) \ + _tc_malloc(__FILE__, __LINE__, size) +#define tc_zalloc(size) \ + _tc_zalloc(__FILE__, __LINE__, size) +#define tc_realloc(p,size) \ + _tc_realloc(__FILE__, __LINE__, p, size) +#define tc_free(ptr) \ + free(ptr); + +/* + * _tc_malloc: + * do the real work behind tc_malloc macro + * + * Parameters: + * file: name of the file on which call occurs + * line: line of above file on which call occurs + * (above two parameters are intended to be, and usually + * are, filled by tc_malloc macro) + * size: size of desired chunk of memory + * Return Value: + * a pointer of acquired memory, or NULL if acquisition fails + * Side effects: + * a message is printed on stderr if acquisition fails + * Preconditions: + * file param not null + */ +void *_tc_malloc(const char *file, int line, size_t size); + +/* + * _tc_zalloc: + * do the real work behind tc_zalloc macro + * + * Parameters: + * file: name of the file on which call occurs + * line: line of above file on which call occurs + * (above two parameters are intended to be, and usually + * are, filled by tc_malloc macro) + * size: size of desired chunk of memory + * Return Value: + * a pointer of acquired memory, or NULL if acquisition fails + * Side effects: + * a message is printed on stderr if acquisition fails + * Preconditions: + * file param not null + * Postconditions: + * if call succeed, acquired memory contains all zeros + */ +void *_tc_zalloc(const char *file, int line, size_t size); + +/* + * _tc_realloc: + * do the real work behind tc_realloc macro + * + * Parameters: + * file: name of the file on which call occurs + * line: line of above file on which call occurs + * (above two parameters are intended to be, and usually + * are, filled by tc_malloc macro) + * p: pointer to reallocate + * size: size of desired chunk of memory + * Return Value: + * a pointer of acquired memory, or NULL if acquisition fails + * Side effects: + * a message is printed on stderr if acquisition fails + * Preconditions: + * file param not null + */ +void *_tc_realloc(const char *file, int line, void *p, size_t size); + +/* + * Allocate a buffer aligned to the machine's page size, if known. The + * buffer must be freed with buffree() (not free()). + */ + +#define tc_bufalloc(size) \ + _tc_bufalloc(__FILE__, __LINE__, size) + +/* + * _tc_malloc: + * do the real work behind _tc_bufalloc macro + * + * Parameters: + * file: name of the file on which call occurs + * line: line of above file on which call occurs + * (above two parameters are intended to be, and usually + * are, filled by tc_malloc macro) + * size: size of desired chunk of memory + * Return Value: + * a pointer of acquired, aligned, memory, or NULL if acquisition fails + * Side effects: + * a message is printed on stderr (20051017) + * Preconditions: + * file param not null + */ + +void *_tc_bufalloc(const char *file, int line, size_t size); + +/* + * tc_buffree: + * release a memory buffer acquired using tc_bufalloc + * + * Parameters: + * ptr: pointer obtained as return value of a succesfull + * tc_bufalloc() call + * Return Value: + * none + * Preconditions: + * ptr is acquired via tc_bufalloc(). Really BAD things will happen + * if a buffer acquired via tc_bufalloc() is released using anything + * but tc_buffree(), or vice versa. + */ +void tc_buffree(void *ptr); + +/*************************************************************************/ + +/* + * tc_strdup: a macro wrapper on top of _tc_strndup, like tc_malloc, above + * tc_strndup: like tc_strdup, but copies only N byte of given string + * + * This function does the same thing of libc's standard function + * strdup(3) and the GNU extension strndup(3), but using libtc's + * tc_malloc features. + */ +#define tc_strdup(s) \ + _tc_strndup(__FILE__, __LINE__, s, strlen(s)) +#define tc_strndup(s, n) \ + _tc_strndup(__FILE__, __LINE__, s, n) + +/* + * _tc_strndup: + * do the real work behind tc_strdup/tc_strndup macro. This function + * adds automatically and implicitely a '\0' terminator at end of + * copied string. + * + * Parameters: + * file: name of the file on which call occurs + * line: line of above file on which call occurs (above two parameters + * are intended to be, and usually are, filled by tc_malloc macro) + * s: null-terminated string to copy + * n: copy at most 'n' characters of original string. + * Return Value: + * a pointer to a copy of given string. This pointer must be freed using + * tc_free() to avoid memory leaks + * Side effects: + * a message is printed on stderr (20051017) + * Preconditions: + * file param not null + * Postconditions: + * none + */ +char *_tc_strndup(const char *file, int line, const char *s, size_t n); + +/* + * tc_file_check: + * verify the type of a given file (path) this function will be + * deprecated very soon, replaced by a powered tc_probe_path(). + * + * Parameters: + * file: the file (really: path) to verify. + * Return Value: + * -1 if an internal error occur + * 0 if given path is really a file + * 1 if given path is a directory + * Side effects: + * none + * Preconditions: + * none + * Postconditions: + * none + */ +int tc_file_check(const char *file); + +/* + * tc_pread: + * read an entire buffer from a file descriptor, restarting + * automatically if interrupted. This function is basically a wrapper + * around posix read(2); read(2) can be interrupted by a signal, + * so doesn't guarantee that all requested bytes are effectively readed + * when read(2) returns; this function ensures so, except for critical + * errors. + * Parameters: + * fd: read data from this file descriptor + * buf: pointer to a buffer which will hold readed data + * len: how much data function must read from fd + * Return Value: + * size of effectively readed data + * Side effects: + * errno is readed internally + * Postconditions: + * read exactly the requested bytes, if no *critical* + * (tipically I/O related) error occurs. + */ +ssize_t tc_pread(int fd, uint8_t *buf, size_t len); + +/* + * tc_pwrite: + * write an entire buffer from a file descriptor, restarting + * automatically if interrupted. This function is basically a wrapper + * around posix write(2); write(2) can be interrupted by a signal, + * so doesn't guarantee that all requested bytes are effectively writed + * when write(2) returns; this function ensures so, except for critical + * errors. + * Parameters: + * fd: write data on this file descriptor + * buf: pointer to a buffer which hold data to be written + * len: how much data function must write in fd + * Return Value: + * size of effectively written data + * Side effects: + * errno is readed internally + * Postconditions: + * write exactly the requested bytes, if no *critical* (tipically I/O + * related) error occurs. + */ +ssize_t tc_pwrite(int fd, const uint8_t *buf, size_t len); + +/* + * tc_preadwrite: + * read all data avalaible from a file descriptor, putting it on the + * other one. + * Parameters: + * in: read data from this file descriptor + * out: write readed data on this file descriptor + * Return Value: + * -1 if a read error happens + * 0 if no error happens + * Postconditions: + * move the entire content of 'in' into 'out', if no *critical* + * (tipically I/O related) error occurs. + */ +int tc_preadwrite(int in, int out); + +enum { + TC_PROBE_PATH_INVALID = 0, + TC_PROBE_PATH_ABSPATH, + TC_PROBE_PATH_RELDIR, + TC_PROBE_PATH_FILE, + TC_PROBE_PATH_BKTR, + TC_PROBE_PATH_SUNAU, + TC_PROBE_PATH_V4L_VIDEO, + TC_PROBE_PATH_V4L_AUDIO, + TC_PROBE_PATH_OSS, + /* add more elements here */ +}; + +/* + * tc_probe_path: + * verify the type of a given path. + * + * Parameters: + * path: the path to probe. + * Return Value: + * the probed type of path. Can be TC_PROBE_PATH_INVALID if given path + * doesn't exists or an internal error occur. + * Side effects: + * if function fails, one or more debug message can be issued using + * tc_log*(). A name resolve request can be issued to system. + */ +int tc_probe_path(const char *name); + +/* codec helpers ***********************************************************/ + +/* + * tc_translate_codec_id: + * translate a CODEC_* value to corresponding TC_CODEC_* one. + * + * Parameters: + * codec: CODEC_* value to translate. + * Return value: + * corresponding TC_CODEC_* value, or + * TC_CODEC_ERROR if given CODEC_XXX hasn't corresponding TC_CODEC_XXX + * or if it;s just unknown. + */ +int tc_translate_codec_id(TCCodecID codec); + +/* + * tc_codec_to_comment: + * return a short constant descriptive string given the codec identifier. + * + * Parameters: + * codec: TC_CODEC_* value to represent. + * Return value: + * a constant string describing the given codec (there is no need to + * free() it). + * Postconditions: + * Always return something sensible, even if unknown codec id was given. + */ +const char* tc_codec_to_comment(TCCodecID codec); + +/* + * tc_codec_to_string: + * return the codec name as a lowercase constant string, + * given the codec identifier. + * + * Parameters: + * codec: the TC_CODEC_* value to represent. + * Return value: + * a constant string representing the given codec (there is no need to + * free() it). + * NULL if codec is (yet) unknown. + */ +const char* tc_codec_to_string(TCCodecID codec); + +/* + * tc_codec_from_string: + * extract codec identifier from its string representation + * + * Parameters: + * codec: string representation of codec, lowercase (name). + * Return value: + * the correspinding TC_CODEC_* of given string representation, + * or TC_CODEC_ERROR if string is unknown or wrong. + */ +TCCodecID tc_codec_from_string(const char *codec); + +/* + * tc_codec_fourcc: + * extract the FOURCC code for a given codec, if exists. + * + * Parameters: + * codec: TC_CODEC_* value to get the FOURCC for. + * Return value: + * a constant string representing the FOURCC for a given codec (there + * is no need to free() it NULL of codec's FOURCC is (yet) unknown or + * given codec has _not_ FOURCC (es: audio codec identifiers). + */ +const char* tc_codec_fourcc(TCCodecID codec); + +/* + * tc_codec_description: + * describe a codec, given its ID. + * + * Parameters: + * codec: TC_CODEC_* value to get the description for. + * buf: buffer provided to caller. Description will be stored here. + * bufsize: size of the given buffer. + * Return value: + * -1 if requested codec isn't known. + * 0 truncation error (given buffer too small). + * >0 no errors. + */ +int tc_codec_description(TCCodecID codec, char *buf, size_t bufsize); + +/* + * tc_codec_is_multipass: + * tell if a given codec is multipass capable or not. + * + * Parameters: + * codec: TC_CODEC_* value to inquiry. + * Return value: + * TC_TRUE: given codec is multipass capable. + * TC_FALSE: given codec is NOT multipass capable OR is not known. + */ +int tc_codec_is_multipass(TCCodecID codec); + +/*************************************************************************/ + +/* + * tc_compute_fast_resize_values: + * compute internal values needed for video frame fast resize (-B/-X) + * given base resolution (ex_v_{width,height}) and target one + * (zoom_{width,height}). + * WARNING: at moment of writing there are some back compatibility + * constraints, nevethless this function interface (notabley I/O + * parameters passing) needs a SERIOUS rethink. + * + * Parameters: + * _vob: pointer to a structure on which read/store values for + * computation. + * Should ALWAYS really be a pointer to a vob_t structure, + * but vob_t pointer isn't used (yet) in order to avoid + * libtc/transcode.h interdependency. + * I'm not yet convinced that those informations should go + * in TCExportInfo because only transcode core needs them. + * Perhaps the cleanest solution is to introduce yet + * another structure :\. + * If anyone has a better solution just let me know -- FR. + * vob_t fields used: + * ex_v_{width, height}: base resolution (In) + * zoom_{width, height}: target resolution (In) + * resize{1,2}_mult, vert_resize{1,2}, hori_resize{1,2}: + * computed parameters (Out) + * strict: if !0, allow only enlarging and shrinking of frame in + * both dimensions, and fail otherwise. + * Return value: + * 0 succesfull + * -1 error, computation failed + * (i.e. width or height not multiple of 8) + * Side effects: + * if succesfull, zoom_{width,height} will be set to 0. + */ +int tc_compute_fast_resize_values(void *_vob, int strict); + +/*************************************************************************/ + +/** + * tc_find_best_aspect_ratio: + * set sar_num and sar_den to the sample aspect ratio (also called + * pixel aspect ratio) described by vob->ex_par, + * vob->ex_par_width, vob->ex_par_height and vob->ex_asr. + * + * This function might return quite high values in sar_num and + * sar_den. Depending on what codec these parameters are given to, + * eventually a common factor should be reduced first. In case of x264 + * this is not needed, because it's done in x264's code. + * + * Parameters: + * vob: constant pointer to vob structure. + * sar_num: integer to store SAR-numerator in. + * sar_den: integer to store SAR-denominator in. + * tag: tag to use in log messages (if any). + * + * Returns: + * 0 on success, nonzero otherwise (this means bad parameters). + */ +int tc_find_best_aspect_ratio(const void *_vob, + int *sar_num, int *sar_den, + const char *tag); + +/*************************************************************************/ + +/* + * XXX: add some general notes about quantization matrices stored + * into files (format etc. etc.) + * + * tc_*_matrix GOTCHA: + * Why _two_ allowed elements wideness? Why this mess? + * The problem is that XviD and libavcodec wants elements for + * quantization matrix in two different wideness. Obviously + * we DON'T want to patch such sources, so we must handle in + * some way this difference. + * Of course we are looking for cleaner solutions. + * -- fromani 20060305 + */ + +/* + * Total size (=number of elements) of quantization matrix + * for following two support functions + */ +#define TC_MATRIX_SIZE (64) + +/* + * tc_read_matrix: + * read a quantization matrix from given file. + * Can read 8-bit wide or 16-bit wide matrix elements. + * Store readed matrix in a caller-provided buffer. + * + * Caller can select the elements wideness just + * providing a not-NULL buffer for corresponding buffer. + * For example, if caller wants to read a quantization matrix + * from 'matrix.txt', and want 16-bit wide elements, it + * will call + * + * uint16_t matrix[TC_MATRIX_SIZE]; + * tc_read_matrix('matrix.txt', NULL, matrix); + * + * Parameters: + * filename: read quantization matrix from this file. + * m8: buffer for 8-bit wide elements quantization matrix + * m16: buffer for 16-bit wide elements quantization matrix + * + * NOTE: if m8 AND m16 BOTH refers to valid buffers, 8-bit + * wideness is preferred. + * Return value: + * -1 filename not found, or neither buffers is valid. + * +1 read error: matrix incomplete or badly formatted. + * 0 no errors. + * Side effects: + * a file on disk is open, readed, closed. + * Preconditions: + * buffer provided by caller MUST be large enough to hold + * TC_MATRIX_SIZE elements of requested wideness. + * At least one given buffer is valid. + */ +int tc_read_matrix(const char *filename, uint8_t *m8, uint16_t *m16); + +/* + * tc_print_matrix: + * print (using tc_log*) a quantization matrix. + * Can print 8-bit wide or 16-bit wide matrix elements. + * + * Caller must provide a valid pointer correspoinding to + * wideness of elements of matrix to be printed. + * Example: quantization matrix has 8-bit wide elements: + * + * uint8_t matrix[TC_MATRIX_SIZE]; + * // already filled with something useful + * tc_print_matrix(matrix, NULL); + * + * Parameters: + * m8: pointer to 8-bit wide elements quantization matrix. + * m16: pointer to 16-bit wide elements quantization matrix. + * + * NOTE: if m8 AND m16 BOTH refers to valid buffers, 8-bit + * wideness is preferred. + * Preconditions: + * At least one given pointer is valid. + */ +void tc_print_matrix(uint8_t *m8, uint16_t *m16); + +#ifdef __cplusplus +} +#endif + +#endif /* _LIBTC_H */ diff --git a/debian/transcode/transcode-1.1.7/libtc/libxio.c b/debian/transcode/transcode-1.1.7/libtc/libxio.c new file mode 100644 index 00000000..fba67b4a --- /dev/null +++ b/debian/transcode/transcode-1.1.7/libtc/libxio.c @@ -0,0 +1,812 @@ +/* + * libxio.c + * + * Copyright (C) Lukas Hejtmanek - January 2004 + * + * This file is part of transcode, a video stream processing tool + * + * transcode 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, or (at your option) + * any later version. + * + * transcode is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Make; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#undef PACKAGE +#undef VERSION + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif +#ifdef HAVE_IBP +#include <lors.h> +#endif +#include <stdio.h> +#include <stdlib.h> +#include <pthread.h> +#include <string.h> +#include <sys/types.h> +#include <unistd.h> +#include <fcntl.h> +#include <sys/stat.h> +#include <errno.h> +#include <stdarg.h> + +#include "libtc.h" +#include "xio.h" + +#define MAX_HANDLES 256 + +static void * xio_handles[MAX_HANDLES]; +static int xio_initialized = 0; +pthread_mutex_t xio_lock; + +#ifdef HAVE_IBP +#define IBP_URI "lors://" +#define IBP_URI_LEN 7 + +#define BLOCK_SIZE_SHIFT 1024 + +#define LBONE_PORT 6767 +#define LORS_BLOCKSIZE 10*1024 +#define LORS_DURATION 3600 +#define LORS_COPIES 1 +#define LORS_THREADS 1 +#define LORS_TIMEOUT 100 +#define LORS_SERVERS 1 +#define LORS_SIZE 10*1024*1024 + +struct xio_ibp_handle_t { + LorsDepotPool *dp; + LorsExnode *ex; + off_t b_pos; + off_t begin; + off_t end; + void *buffer; + char *filename; + char *lbone_server; + int lbone_port; + int lors_blocksize; + int lors_duration; + int lors_copies; + int lors_threads; + int lors_timeout; + int lors_servers; + off_t lors_size; + int fill_buffer; + int dirty_buffer; + int mode; +}; + +static void * +ibp_open(const char *uri, int mode, int m) +{ + struct xio_ibp_handle_t *handle; + int ret; + + if(strncmp(uri, IBP_URI, IBP_URI_LEN) != 0) { + errno = EINVAL; + return (void *)-1; + } + uri += IBP_URI_LEN; + + handle=(struct xio_ibp_handle_t*)calloc(1, + sizeof(struct xio_ibp_handle_t)); + + // environment setup + handle->lbone_server = getenv("LBONE_SERVER"); + if(getenv("LBONE_PORT")) { + handle->lbone_port = atoi(getenv("LBONE_PORT")); + } else { + handle->lbone_port = LBONE_PORT; + } + + if(getenv("LORS_BLOCKSIZE")) { + handle->lors_blocksize = atoi(getenv("LORS_BLOCKSIZE")); + } else { + if(mode & O_WRONLY || mode & O_CREAT) + handle->lors_blocksize = LORS_BLOCKSIZE; + else + handle->lors_blocksize = 128; + } + + if(getenv("LORS_DURATION")) { + handle->lors_duration = atoi(getenv("LORS_DURATION")); + } else { + handle->lors_duration = LORS_DURATION; + } + + if(getenv("LORS_COPIES")) { + handle->lors_copies = atoi(getenv("LORS_COPIES")); + } else { + handle->lors_copies = LORS_COPIES; + } + + if(getenv("LORS_THREADS")) { + handle->lors_threads = atoi(getenv("LORS_THREADS")); + } else { + handle->lors_threads = LORS_THREADS; + } + + if(getenv("LORS_TIMEOUT")) { + handle->lors_timeout = atoi(getenv("LORS_TIMEOUT")); + } else { + handle->lors_timeout = LORS_TIMEOUT; + } + + if(getenv("LORS_SERVERS")) { + handle->lors_servers = atoi(getenv("LORS_SERVERS")); + } else { + handle->lors_servers = LORS_SERVERS; + } + + if(getenv("LORS_SIZE")) { + handle->lors_servers = atoi(getenv("LORS_SIZE")); + } else { + handle->lors_servers = LORS_SIZE; + } + + if(*uri != '/') { + // get LBONE_SERVER from URI + if(strchr(uri, ':')) { + // port is defined + handle->lbone_server = tc_strndup(uri, + strchr(uri, ':')-uri); + uri = (char *)(strchr(uri, ':')+1); + handle->lbone_port = atoi(uri); + } else { + // only host + handle->lbone_server = tc_strndup(uri, + (int)(strchr(uri, '/')-uri)); + } + uri = (char *)(strchr(uri, '/')+1); + } else { + uri += 1; + } + + if(!strchr(uri, '?')) { + // only filename + handle->filename = strdup(uri); + } else { + // parse options + handle->filename = tc_strndup(uri, (int)(strchr(uri, '?')-uri)); + uri = strchr(uri, '?')+1; + while(uri != (char *)1) { + if(strncmp(uri, "bs", 2) == 0) { + handle->lors_blocksize = atoi(&uri[3]); + } else if(strncmp(uri, "duration", 8) == 0) { + handle->lors_duration = atoi(&uri[9]); + } else if(strncmp(uri, "copies", 6) == 0) { + handle->lors_copies = atoi(&uri[7]); + } else if(strncmp(uri, "threads", 7) == 0) { + handle->lors_threads = atoi(&uri[8]); + } else if(strncmp(uri, "timeout", 7) == 0) { + handle->lors_timeout = atoi(&uri[8]); + } else if(strncmp(uri, "servers", 7) == 0) { + handle->lors_servers = atoi(&uri[8]); + } else if(strncmp(uri, "size", 4) == 0) { + handle->lors_size = atoi(&uri[5]); + } + uri = strchr(uri, '&') + 1; + } + } + + handle->lors_blocksize *= BLOCK_SIZE_SHIFT; + + handle->mode = mode; + handle->b_pos = 0; + handle->begin = 0; + handle->end = 0; + handle->dirty_buffer = 0; + + if(mode & O_WRONLY || mode & O_CREAT) { + handle->buffer = malloc(handle->lors_blocksize); + if(!handle->buffer) { + free(handle); + errno = EIO; + return (void *)-1; + } + ret = lorsGetDepotPool(&handle->dp, handle->lbone_server, + handle->lbone_port, NULL, + handle->lors_servers, NULL, + handle->lors_size/(1024*1024)+1, + IBP_HARD, + handle->lors_duration, + handle->lors_threads, + handle->lors_timeout, + LORS_CHECKDEPOTS); + if(ret != LORS_SUCCESS) { + errno = EIO; + return (void *)-1; + } + ret = lorsExnodeCreate(&handle->ex); + if (ret != LORS_SUCCESS) { + errno = EIO; + return (void *)-1; + } + } + if(mode & O_RDONLY || !mode) { + handle->buffer = malloc(handle->lors_blocksize); + handle->fill_buffer = 1; + ret = lorsFileDeserialize(&handle->ex, handle->filename, NULL); + if(ret != LORS_SUCCESS) { + errno = EIO; + return (void *)-1; + } + ret = lorsUpdateDepotPool(handle->ex, &handle->dp, + handle->lbone_server, 0, + NULL, handle->lors_threads, + handle->lors_timeout, 0); + if(ret != LORS_SUCCESS) { + errno = EIO; + return (void *)-1; + } + } + return (void *)handle; +} + + +static int +ibp_flush(void *handle) +{ + struct xio_ibp_handle_t *hdl = (struct xio_ibp_handle_t *)handle; + int ret; + LorsSet *set; + + if(hdl->dirty_buffer == 0) { + return 0; + } + + ret = lorsQuery(hdl->ex, &set, hdl->begin, hdl->end, + LORS_QUERY_REMOVE); + if(ret != LORS_SUCCESS) { + errno = EINVAL; + return -1; + } + + if(jrb_empty(set->mapping_map)) { + ret = lorsSetInit(&set, hdl->end/hdl->lors_threads, 1, 0); + if(ret != LORS_SUCCESS) { + errno = EIO; + return -1; + } + + ret = lorsSetStore(set, hdl->dp, hdl->buffer, + hdl->begin, hdl->end, NULL, + hdl->lors_threads, + hdl->lors_timeout, LORS_RETRY_UNTIL_TIMEOUT); + + if(ret != LORS_SUCCESS) { + lorsSetFree(set,LORS_FREE_MAPPINGS); + errno = EIO; + return -1; + } + } else { + set->copies=hdl->lors_copies; + set->data_blocksize=hdl->end/hdl->lors_threads; + ret = lorsSetUpdate(set, hdl->dp, hdl->buffer, + hdl->begin, hdl->end, + hdl->lors_threads,hdl->lors_timeout, + LORS_RETRY_UNTIL_TIMEOUT); + if(ret != LORS_SUCCESS) { + lorsSetFree(set,LORS_FREE_MAPPINGS); + errno=EIO; + return -1; + } + } + + ret = lorsAppendSet(hdl->ex, set); + if(ret != LORS_SUCCESS) { + lorsSetFree(set, LORS_FREE_MAPPINGS); + errno=EIO; + return -1; + } + + lorsSetFree(set,0); + + hdl->begin += hdl->b_pos; + + hdl->end = 0; + + ret = lorsFileSerialize(hdl->ex, hdl->filename, 0, 0); + + if(ret != LORS_SUCCESS) { + perror("file serialize"); + } + + hdl->dirty_buffer = 0; + return 0; +} + +static ssize_t +ibp_write(void *handle, const void *buffer, size_t size) +{ + struct xio_ibp_handle_t *hdl = (struct xio_ibp_handle_t *)handle; + + pthread_testcancel(); + pthread_mutex_lock(&xio_lock); + pthread_testcancel(); + if(size > hdl->lors_blocksize) + size = hdl->lors_blocksize; + + if(!hdl || !buffer || hdl->mode == O_RDONLY || !hdl->buffer) { + errno = EINVAL; + pthread_mutex_unlock(&xio_lock); + return -1; + } + + hdl->dirty_buffer = 1; + + if(hdl->b_pos + size >= hdl->lors_blocksize) { + if(ibp_flush(handle)) { + errno = EIO; + pthread_mutex_unlock(&xio_lock); + return -1; + } + hdl->b_pos = 0; + } + + memcpy((char *)hdl->buffer + hdl->b_pos, buffer, size); + hdl->b_pos += size; + if(hdl->end < hdl->b_pos) + hdl->end = hdl->b_pos; + + pthread_mutex_unlock(&xio_lock); + return size; +} + +static ssize_t +ibp_read(void *handle, void *buffer, size_t size) +{ + struct xio_ibp_handle_t *hdl = (struct xio_ibp_handle_t *)handle; + int ret; + int msize=size; + LorsSet *set; + + pthread_testcancel(); + pthread_mutex_lock(&xio_lock); + pthread_testcancel(); + + if(hdl->mode == O_WRONLY) { + errno = EINVAL; + pthread_mutex_unlock(&xio_lock); + return -1; + } + + if(size > hdl->lors_blocksize - hdl->b_pos) + msize = hdl->lors_blocksize - hdl->b_pos; + + if(hdl->b_pos < hdl->lors_blocksize && !hdl->fill_buffer) { + memcpy(buffer, hdl->buffer+hdl->b_pos, msize); + hdl->b_pos += msize; + pthread_mutex_unlock(&xio_lock); + return msize; + } + + hdl->fill_buffer = 0; + + ret = lorsQuery(hdl->ex, &set, hdl->begin + hdl->b_pos, + hdl->lors_blocksize, 0); + if(ret != LORS_SUCCESS) { + pthread_mutex_unlock(&xio_lock); + return 0; + } + + ret = lorsSetLoad(set, hdl->buffer, hdl->begin + hdl->b_pos, + hdl->lors_blocksize, hdl->lors_blocksize, + NULL, hdl->lors_threads, hdl->lors_timeout, 0); + + lorsSetFree(set, 0); + + if(ret < 0) { + errno = EIO; + pthread_mutex_unlock(&xio_lock); + return -1; + } + + hdl->begin += hdl->b_pos; + + if(size > ret) + size = ret; + + hdl->b_pos = size; + memcpy(buffer, hdl->buffer, size); + pthread_mutex_unlock(&xio_lock); + return size; +} + +static off_t +ibp_lseek(void *handle, off_t offs, int mode) +{ + struct xio_ibp_handle_t *hdl = (struct xio_ibp_handle_t *)handle; + + pthread_mutex_lock(&xio_lock); + pthread_testcancel(); + if(mode == SEEK_SET) { + if(offs - hdl->begin > hdl->lors_blocksize || + offs < hdl->begin) { + if(ibp_flush(handle)) { + errno = EIO; + pthread_mutex_unlock(&xio_lock); + return -1; + } + hdl->fill_buffer = 1; + hdl->begin = offs; + hdl->b_pos = 0; + } else { + hdl->b_pos = offs - hdl->begin; + } + } + else if(mode == SEEK_CUR) { + if(hdl->b_pos + offs > hdl->lors_blocksize || + hdl->b_pos + offs < 0) { + if(ibp_flush(handle)) { + errno = EIO; + pthread_mutex_unlock(&xio_lock); + return -1; + } + hdl->fill_buffer = 1; + hdl->begin = hdl->begin + hdl->b_pos + offs; + hdl->b_pos = 0; + } else { + hdl->b_pos += offs; + } + } else if(mode == SEEK_END) { + if(ibp_flush(handle)) { + errno = EIO; + pthread_mutex_unlock(&xio_lock); + return -1; + } + hdl->fill_buffer = 1; + hdl->begin = hdl->ex->logical_length + offs; + hdl->b_pos = 0; + } else { + errno=EINVAL; + pthread_mutex_unlock(&xio_lock); + return(-1); + } + + pthread_mutex_unlock(&xio_lock); + return hdl->begin + hdl->b_pos; +} + +static int +ibp_close(void *handle) +{ + struct xio_ibp_handle_t *hdl = (struct xio_ibp_handle_t *)handle; + int ret; + + pthread_mutex_lock(&xio_lock); + pthread_testcancel(); + if(hdl->mode & O_WRONLY || hdl->mode & O_CREAT) { + if(hdl->dirty_buffer) + ibp_flush(handle); + else { + ret = lorsFileSerialize(hdl->ex, hdl->filename, 0, 0); + if(ret != LORS_SUCCESS) { + perror("file serialize"); + } + } + } + if(hdl->buffer) + free(hdl->buffer); + ret = lorsExnodeFree(hdl->ex); + if(ret != LORS_SUCCESS) { + perror("exnode free"); + } + if(!hdl) { + pthread_mutex_unlock(&xio_lock); + return 0; + } + if(hdl->dp) + lorsFreeDepotPool(hdl->dp); + pthread_mutex_unlock(&xio_lock); + free(hdl); + return 0; +} + +static int +ibp_ftruncate(void *stream, off_t length) +{ + struct xio_ibp_handle_t* hdl = (struct xio_ibp_handle_t*)stream; + int ret; + LorsSet *set; + + pthread_mutex_lock(&xio_lock); + pthread_testcancel(); + ibp_flush(stream); + hdl->b_pos = 0; + if(length == hdl->ex->logical_length) { + pthread_mutex_unlock(&xio_lock); + return 0; + } + + ret = lorsQuery(hdl->ex, &set, length, + hdl->ex->logical_length-length, 0); + if(ret != LORS_SUCCESS) { + pthread_mutex_unlock(&xio_lock); + errno = EINVAL; + return -1; + } + ret = lorsSetTrim(set, length, hdl->ex->logical_length-length, + 1, 20, LORS_TRIM_ALL); + lorsSetFree(set, 0); + if(ret != LORS_SUCCESS) { + pthread_mutex_unlock(&xio_lock); + errno = EIO; + return -1; + } + pthread_mutex_unlock(&xio_lock); + return 0; +} + +static char * +ibp_lorstoname(char *file_name) +{ + char * uri = file_name; + if(strncmp(uri, IBP_URI, IBP_URI_LEN) != 0) { + return strdup(uri); + } + uri += IBP_URI_LEN; + uri = (char *)(strchr(uri, '/')+1); + if(!strchr(uri, '?')) { + return strdup(uri); + } + return tc_strndup(uri, (int)(strchr(uri, '?')-uri)); +} + +static int +ibp_stat(const char *file_name, struct stat *buf) +{ + LorsExnode *exnode; + int ret; + char *fn; + + fn = ibp_lorstoname((char *)file_name); + ret = lorsFileDeserialize(&exnode, fn, NULL); + if(ret!=0) { + errno=EACCES; + return -1; + } + if(stat(fn, buf) == -1) { + free(fn); + return -1; + } + buf->st_ino=-1; + buf->st_dev=-1; + buf->st_size=exnode->logical_length; + lorsExnodeFree(exnode); + free(fn); + return 0; +} + +static int +ibp_lstat(const char *file_name, struct stat *buf) +{ + char *fn = ibp_lorstoname((char *)file_name); + if(lstat(fn,buf) == -1) { + free(fn); + return -1; + } + free(fn); + return 0; +} + +static int +ibp_fstat(void *stream, struct stat *buf) +{ + struct xio_ibp_handle_t *hdl = (struct xio_ibp_handle_t *)stream; + + return ibp_stat(hdl->filename,buf); +} + +#endif + + + +#define XIO_VALID_FD(fd) \ + ((fd) > 2 && (fd) < MAX_HANDLES) + +#define XIO_HAS_HANDLE(fd) \ + (XIO_VALID_FD(fd) && (xio_handles[(fd)] != NULL)) + +#define XIO_CHECK_INIT \ + if(!xio_initialized) { \ + xio_init(); \ + xio_initialized = 1; \ + } + +static void +xio_init(void) +{ + int i; + + for (i = 0; i < MAX_HANDLES; i++) { + xio_handles[i] = NULL; + } + + pthread_mutex_init(&xio_lock, NULL); +} + +int +xio_open(const char *pathname, int flags, ...) +{ + int i; + int hid; + int mode = 0; + + XIO_CHECK_INIT; + + if(flags & O_CREAT) { + va_list arg; + va_start(arg, flags); + mode = va_arg(arg, int); + va_end(arg); + } + + pthread_mutex_lock(&xio_lock); + /* Find free IO handle, skipping stdin, stdout, stderr */ + for(i = 3; xio_handles[i] != NULL && i < MAX_HANDLES; i++) { + ; /* do nothing in loop body */ + } + hid = (i == MAX_HANDLES) ?-1 :i; + pthread_mutex_unlock(&xio_lock); + + if(hid == -1) { + errno = EIO; + return -1; + } + +#ifdef HAVE_IBP + if(strncmp(pathname, IBP_URI, IBP_URI_LEN) == 0) { + // IBP uri + xio_handles[hid] = ibp_open(pathname, flags, mode); + if(!xio_handles[hid]) { + errno = EIO; + return -1; + } + return hid; + } +#endif + return open(pathname, flags, mode); +} + +ssize_t +xio_read(int fd, void *buf, size_t count) +{ + XIO_CHECK_INIT; + +#ifdef HAVE_IBP + if(XIO_HAS_HANDLE(fd)) { + return ibp_read(xio_handles[fd], buf, count); + } +#endif + return read(fd, buf, count); +} + +ssize_t +xio_write(int fd, const void *buf, size_t count) +{ + XIO_CHECK_INIT; + +#ifdef HAVE_IBP + if(XIO_HAS_HANDLE(fd)) { + return ibp_write(xio_handles[fd], buf, count); + } +#endif + return write(fd, buf, count); +} + +int +xio_ftruncate(int fd, off_t length) +{ + XIO_CHECK_INIT; + +#ifdef HAVE_IBP + if(XIO_HAS_HANDLE(fd)) { + return ibp_ftruncate(xio_handles[fd], length) + } +#endif + return ftruncate(fd, length); +} + +off_t +xio_lseek(int fd, off_t offset, int whence) +{ + XIO_CHECK_INIT; + +#ifdef HAVE_IBP + if(XIO_HAS_HANDLE(fd)) { + return ibp_lseek(xio_handles[fd], offset, whence); + } +#endif + return lseek(fd, offset, whence); +} + +int +xio_close(int fd) +{ + XIO_CHECK_INIT; + +#ifdef HAVE_IBP + if(XIO_HAS_HANDLE(fd)) { + int ret = ibp_close(xio_handles[fd]); + xio_handles[fd] = NULL; + return ret; + } +#endif + return close(fd); +} + +int +xio_stat(const char *file_name, struct stat *buf) +{ + XIO_CHECK_INIT; + +#ifdef HAVE_IBP + if(strncmp(file_name, IBP_URI, IBP_URI_LEN) == 0) { + return ibp_stat(file_name, buf); + } +#endif + return stat(file_name, buf); +} + +int +xio_lstat(const char *file_name, struct stat *buf) +{ + XIO_CHECK_INIT; + +#ifdef HAVE_IBP + if(strncmp(file_name, IBP_URI, IBP_URI_LEN) == 0) { + return ibp_lstat(file_name, buf); + } +#endif + return lstat(file_name, buf); +} + +int +xio_rename(const char *oldpath, const char *newpath) +{ +#ifdef HAVE_IBP + char *old, *old_p; + char *newp; + int ret; + + if(strncmp(IBP_URI, oldpath, IBP_URI_LEN) == 0) { + old_p = old = strdup(oldpath); + old = strchr(old + IBP_URI_LEN,'/')+1; + if(strchr(old, '?')) { + *(strchr(old, '?')) = 0; + } + + newp = malloc(strlen(old)+1+4); + snprintf(newp, strlen(old)+1+4, "%s%s", old, &newpath[strlen(newpath)-4]); + ret = rename(old, newp); + free(old_p); + return ret; + } +#endif + return rename(oldpath, newpath); +} + +int +xio_fstat(int fd, struct stat *buf) +{ + XIO_CHECK_INIT; + +#ifdef HAVE_IBP + if(XIO_HAS_HANDLE(fd)) { + return ibp_fstat(xio_handles[fd], buf) + } +#endif + return fstat(fd, buf); +} diff --git a/debian/transcode/transcode-1.1.7/libtc/optstr.c b/debian/transcode/transcode-1.1.7/libtc/optstr.c new file mode 100644 index 00000000..4ca233ae --- /dev/null +++ b/debian/transcode/transcode-1.1.7/libtc/optstr.c @@ -0,0 +1,265 @@ +/* + * optstr.c + * + * Copyright (C) Tilmann Bitterberg 2003 + * + * Description: A general purpose option string parser + * + * Usage: see optstr.h, please + * + * This file is part of transcode, a video stream processing tool + * + * transcode 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, or (at your option) + * any later version. + * + * transcode is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Make; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +/* for vsscanf */ +#ifdef HAVE_VSSCANF +# define _GNU_SOURCE +#endif + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <stdarg.h> +#include "optstr.h" +#include "libtc.h" + +const char* optstr_lookup(const char *haystack, const char *needle) +{ + const char *ch = haystack; + int found = 0; + size_t len = strlen(needle); + + while (!found) { + ch = strstr(ch, needle); + + /* not in string */ + if (!ch) { + break; + } + + /* do we want this hit? ie is it exact? */ + if (ch[len] == '\0' || ch[len] == '=' || ch[len] == ARG_SEP) { + found = 1; + } else { + /* go a little further */ + ch++; + } + } + + return ch; +} + +int optstr_get(const char *options, const char *name, const char *fmt, ...) +{ + va_list ap; /* points to each unnamed arg in turn */ + int num_args = 0, n = 0; + size_t pos, fmt_len = strlen(fmt); + const char *ch = NULL; + +#ifndef HAVE_VSSCANF + void *temp[ARG_MAXIMUM]; +#endif + + ch = optstr_lookup(options, name); + if (!ch) { + return -1; + } + + /* name IS in options */ + + /* Find how many arguments we expect */ + for (pos = 0; pos < fmt_len; pos++) { + if (fmt[pos] == '%') { + ++num_args; + /* is this one quoted with '%%' */ + if (pos + 1 < fmt_len && fmt[pos + 1] == '%') { + --num_args; + ++pos; + } + } + } + +#ifndef HAVE_VSSCANF + if (num_args > ARG_MAXIMUM) { + fprintf (stderr, + "(%s:%d) Internal Overflow; redefine ARG_MAXIMUM (%d) to something higher\n", + __FILE__, __LINE__, ARG_MAXIMUM); + return -2; + } +#endif + + n = num_args; + /* Bool argument */ + if (num_args <= 0) { + return 0; + } + + /* skip the `=' (if it is one) */ + ch += strlen( name ); + if( *ch == '=' ) + ch++; + + if( !*ch ) + return 0; + + va_start(ap, fmt); + +#ifndef HAVE_VSSCANF + while (--n >= 0) { + temp[num_args - n - 1] = va_arg(ap, void *); + } + + n = sscanf(ch, fmt, + temp[0], temp[1], temp[2], temp[3], temp[4], + temp[5], temp[6], temp[7], temp[8], temp[9], + temp[10], temp[11], temp[12], temp[13], temp[14], + temp[15]); + +#else + /* this would be very nice instead of the above, + * but it does not seem portable + */ + n = vsscanf(ch, fmt, ap); +#endif + + va_end(ap); + + return n; +} + +static int optstr_is_string_arg(const char *fmt) +{ + if (!fmt) { + return 0; + } + if (!strlen(fmt)) { + return 0; + } + if (strchr(fmt, 's')) { + return 1; + } + if (strchr(fmt, '[') && strchr(fmt, ']')) { + return 1; + } + return 0; +} + + +int optstr_filter_desc(char *buf, + const char *filter_name, + const char *filter_comment, + const char *filter_version, + const char *filter_author, + const char *capabilities, + const char *frames_needed) +{ + int len = strlen(buf); + if (tc_snprintf(buf + len, ARG_CONFIG_LEN - len, + "\"%s\", \"%s\", \"%s\", \"%s\", \"%s\", \"%s\"\n", + filter_name,filter_comment,filter_version, + filter_author, capabilities, frames_needed) <= 0) { + return 1; + } + return 0; +} + +int optstr_frames_needed(const char *filter_desc, int *needed_frames) +{ + const char *s = NULL; + + if ((s = strrchr(filter_desc, ',')) == NULL) { + return 1; + } + if ((s = strchr(s, '\"')) == NULL) { + return 1; + } + + *needed_frames = strtol(s + 1, NULL, 0); + return 0; +} + +int optstr_param(char *buf, + const char *name, + const char *comment, + const char *fmt, + const char *val, + ...) /* char *valid_from1, char *valid_to1, ... */ +{ + va_list ap; + int n = 0, res = 0, num_args=0; + size_t buf_len = strlen(buf), fmt_len = strlen(fmt), pos = 0; + + res = tc_snprintf(buf + buf_len, ARG_CONFIG_LEN - buf_len, + "\"%s\", \"%s\", \"%s\", \"%s\"", + name, comment, fmt, val); + if(res <= 0) { + return 1; + } + n += res; + + /* count format strings */ + for (pos = 0; pos < fmt_len; pos++) { + if (fmt[pos] == '%') { + ++num_args; + /* is this one quoted with '%%' */ + if (pos + 1 < fmt_len && fmt[pos + 1] == '%') { + --num_args; + ++pos; + } + } + } + num_args *= 2; + + if (num_args && optstr_is_string_arg(fmt)) { + num_args = 0; + } + + va_start(ap, val); + while (num_args--) { + res = tc_snprintf(buf + buf_len + n, + ARG_CONFIG_LEN - buf_len - n, + ", \"%s\"", va_arg(ap, char *)); + if (res <= 0) { + return 1; + } + n += res; + } + va_end(ap); + + res = tc_snprintf(buf + buf_len + n, ARG_CONFIG_LEN - buf_len - n, "\n"); + if (res <= 0 ) { + return 1; + } + + return 0; +} + +/*************************************************************************/ + +/* + * Local variables: + * c-file-style: "stroustrup" + * c-file-offsets: ((case-label . *) (statement-case-intro . *)) + * indent-tabs-mode: nil + * End: + * + * vim: expandtab shiftwidth=4: + */ diff --git a/debian/transcode/transcode-1.1.7/libtc/optstr.h b/debian/transcode/transcode-1.1.7/libtc/optstr.h new file mode 100644 index 00000000..1d7d79db --- /dev/null +++ b/debian/transcode/transcode-1.1.7/libtc/optstr.h @@ -0,0 +1,213 @@ +/* + * optstr.h + * + * Copyright (C) Tilmann Bitterberg 2003 + * + * This file is part of transcode, a video stream processing tool + * + * transcode 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, or (at your option) + * any later version. + * + * transcode is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Make; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +/* + * optstr is a general purpose option string parser + * + * Usage example: + * int main (void) + * { + * int sum, top, bottom, quant; + * int n; + * char s[100]; + * char options[] = "ranges=5-10:range=8,12,100:percent=16%:help"; + * + * if (optstr_get (options, "help", "") >= 0) + * usage(); + * + * optstr_get (options, "range", "%d,%d,%d", &bottom, &top, &sum); + * optstr_get (options, "ranges", "%d-%d", &bottom, &top); + * optstr_get (options, "range", "%d,%d", &bottom, &top); + * optstr_get (options, "string", "%[^:]", s); + * n = optstr_get (options, "percent", "%d%%", &quant); + * printf("found %d argumens\n", n); + * + * return 0; + * } + * + */ + +#ifndef OPTSTR_H +#define OPTSTR_H + +#define ARG_MAXIMUM (16) +#define ARG_SEP ':' +#define ARG_CONFIG_LEN 8192 + +/* + * optstr_lookup: + * Finds the _exact_ 'needle' in 'haystack' (naming intentionally + * identical to the 'strstr' (3) linux man page) + * + * Parameters: + * needle: substring to be searched + * haystack: string which is supposed to contain the substring + * Return Value: + * constant pointer to first substring found, or NULL if substring + * isn't found. + * Side effects: + * none + * Preconditions: + * none + * Postconditions: + * none + */ +const char * optstr_lookup(const char *haystack, const char *needle); + +/* + * optstr_get: + * extract values from option string + * + * Parameters: + * options: a null terminated string of options to parse, + * syntax is "opt1=val1:opt_bool:opt2=val1-val2" + * where ':' is the seperator. + * name: the name to look for in options; eg "opt2" + * fmt: the format to scan values (printf format); eg "%d-%d" + * (...): variables to assign; eg &lower, &upper + * Return value: + * -2 internal error + * -1 `name' is not in `options' + * 0 `name' is in `options' + * >0 number of arguments assigned + * Side effects: + * none + * Preconditions: + * none + * Postconditions: + * none + */ +int optstr_get(const char *options, const char *name, const char *fmt, ...) +#ifdef HAVE_GCC_ATTRIBUTES +__attribute__((format(scanf,3,4))) +#endif +; + +/* + * optstr_filter_desc: + * Generate a Description of a filter; this description will be a row in + * CSV format. Example: + * "filter_foo", "comment", "0.1", "no@one", "VRY", "1"\n + * WARNING: this function will be deprecated soon since new capabilities + * code has more flexibility and expressiveness. + * + * Parameters: + * buf: a write buffer, will contain the result of the function. 'buf' + * must be at least ARG_CONFIG_LEN characters large. + * filter_(name|comment|version|author): + * obvious, various filter meta data + * capabilities: string of filter capabilities. + * "V": Can do Video + * "A": Can do Audio + * "R": Can do RGB + * "Y": Can do YUV420 + * "4": Can do YUV422 + * "M": Can do Multiple Instances + * "E": Is a PRE filter + * "O": Is a POST filter + * Valid examples: + * "VR" : Video and RGB + * "VRY" : Video and YUV and RGB + * frames_needed: a string of how many frames the filter needs + * to take effect. Usually this is "1". + * Return value: + * 1 Not enough space in `buf' parameter + * 0 Successfull + * Side effects: + * none + * Preconditions: + * none + * Postconditions: + * none + */ +int optstr_filter_desc(char *buf, + const char *filter_name, + const char *filter_comment, + const char *filter_version, + const char *filter_author, + const char *capabilities, + const char *frames_needed); + +/* + * optstr_frames_needed: + * extract the how many frames the filter needs from an CSV row. + * + * Parameters: + * filter_desc: the CSV row + * needed_frames: the result will be stored in this variable + * Return value: + * 1 An error happend + * 0 Successfull + * Side effects: + * none + * Preconditions: + * none + * Postconditions: + * none + */ +int optstr_frames_needed(const char *filter_desc, int *needed_frames); + +/* + * optstr_param: + * Generate a description of one filter parameter. The output will be + * in CSV format. + * Example: "radius", "Search radius", "%d", "8", "8", "24"\n + * + * Parameters: + * buf: a write buffer, will contain the result of the function. 'buf' + * must be at least ARG_CONFIG_LEN characters large. + * name: the name of the parameter (eg "radius") + * comment: a short description (eg "Search radius") + * fmt: a printf style parse string (eg "%d") + * val: current value (eg "8") + * (...): always pairs (but this is actually NOT checked): legal values + * for the parameter (eg "8", "24" -- meaning, the radius + * parameter is valid from 8 to 24). + * Return value: + * 1 An Error happened + * 0 Successfull + * Side effects: + * none + * Preconditions: + * none + * Postconditions: + * none + * + * More examples: + * "pos", "Position (0-width x 0-height)", "%dx%d", "0x0", "0", "width", "0", "height" + * "%dx%d" is interesting, because this parameter takes two values in this format + * so we must supply two ranges (one for each parameter), when this + * param is valid ("0", "width", "0", "height") + * + * "flip", "Mirror image", "", "0" + * This is a boolean, defaults to false. A boolean has no argument, eg "filter_foo=flip" + * + */ +int optstr_param(char *buf, + const char *name, + const char *comment, + const char *fmt, + const char *val, + ...); /* char *valid_from1, char *valid_to1 */ + +#endif /* OPTSTR_H */ diff --git a/debian/transcode/transcode-1.1.7/libtc/ratiocodes.c b/debian/transcode/transcode-1.1.7/libtc/ratiocodes.c new file mode 100644 index 00000000..0975266e --- /dev/null +++ b/debian/transcode/transcode-1.1.7/libtc/ratiocodes.c @@ -0,0 +1,296 @@ +/* + * ratiocodes.c -- database for all ratio/codes (asr, sar, dar, frc...) + * used in transcode + * (C) 2005-2010 - Francesco Romani <fromani -at- gmail -dot- com> + * + * This file is part of transcode, a video stream processing tool. + * + * transcode 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. + * + * transcode is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + + + +#include "libtc.h" +#include "ratiocodes.h" + +#include <stdlib.h> +#include <math.h> + + +#define TABLE_LEN(tab) (sizeof((tab))/sizeof((tab)[0])) + +/* WARNING: this table MUST BE in frc order */ +static const double frc_table[16] = { + 0, + (24000.0/1001.0), + 24, + 25, + (30000.0/1001.0), + 30, + 50, + (2*(30000.0/1001.0)), + 60, + 1, + 5, + 10, + 12, + 15, + 0, + 0 +}; + +/* WARNING: this table MUST BE in asr order */ +static const double asr_table[8] = { + 0.0, + 1.0, + (4.0/3.0), + (16.0/9.0), + (221.0/100.0), + 0.0, + 0.0, + 0.0, +}; + + +/* WARNING: this table MUST BE in frc order */ +static const TCPair frc_ratios[16] = { + { 0, 0 }, + { 24000, 1001 }, + { 24000, 1000 }, + { 25000, 1000 }, + { 30000, 1001 }, + { 30000, 1000 }, + { 50000, 1000 }, + { 60000, 1001 }, + { 60000, 1000 }, + /* XXX */ + { 1000, 1000 }, + { 5000, 1000 }, + { 10000, 1000 }, + { 12000, 1000 }, + { 15000, 1000 }, + /* XXX */ + { 0, 0 }, + { 0, 0 }, +}; + +/* WARNING: this table MUST BE in asr order */ +static const TCPair asr_ratios[8] = { + { 0, 0 }, + { 1, 1 }, + { 4, 3 }, + { 16, 9 }, + { 221, 100 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + /* + * XXX: import/tcprobe.c also claims that + * asr == 8 and asr == 12 are 4:3. + * Need further investigation. + */ +}; + +static const TCPair par_ratios[8] = { + { 1, 1 }, + { 1, 1 }, + { 1200, 1100 }, + { 1000, 1100 }, + { 1600, 1100 }, + { 4000, 3300 }, + { 1, 1 }, + { 1, 1 } +}; + +/*************************************************************************/ + + +const char *tc_asr_code_describe(int asr_code) +{ + switch (asr_code) { + case 1: + return "encoded @ 1:1"; + case 2: + return "encoded @ 4:3"; + case 3: + return "encoded @ 16:9"; + case 4: + return "encoded @ 2.21:1"; + case 8: + return "encoded @ 4:3"; + case 12: + return "encoded @ 4:3"; + } + return "encoded @ UNKNOWN"; +} + + +#define DELTA 0.0005 +static int tc_guess_code_from_value(const double *pairs, size_t len, + int *code, double val) +{ + int idx = TC_NULL_MATCH, i = 0; + double mindiff = DELTA; + + for (i = 0; i < len; i++) { + double diff = fabs(pairs[i] - val); + if (diff < mindiff) { + mindiff = diff; + idx = i; + } + } + if (code != NULL && idx != TC_NULL_MATCH) { + *code = idx; + } + return idx; +} +#undef DELTA + + +int tc_asr_code_from_value(int *asr_code, double ratio) +{ + return tc_guess_code_from_value(asr_table, TABLE_LEN(frc_table), + asr_code, ratio); +} + + +int tc_frc_code_from_value(int *frc_code, double fps) +{ + return tc_guess_code_from_value(frc_table, TABLE_LEN(frc_table), + frc_code, fps); +} + + +int tc_frc_code_to_value(int frc_code, double *fps) +{ + if ((fps != NULL && frc_code >= 0) + && frc_code <= TABLE_LEN(frc_table)) { + *fps = frc_table[frc_code]; + return 0; + } + return TC_NULL_MATCH; +} + +/* + * match_ratio: + * helper for various detection functions. Scans a ratio + * table (that MUST be in frc order) looking for corrispondences + * between a ratio and a ratio code. + * + * Parameters: + * pairs: pointer to an array of TCPair to scan + * len: number of pairs to consider + * n: numerator of ratio to look for. Use TC_NULL_MATCH + * if this function must look for a corrispondency of code + * and not for a corrispondency of ratio. + * d: denominator of ratio to look for. Use TC_NULL_MATCH + * if this function must look for a corrispondency of code + * and not for a corrispondency of ratio. + * code: code of ratio to look for. Use TC_NULL_MATCH if this function + * must look for a corrispondency of ratio. + * Return Value: + * TC_NULL_MATCH if input parameter(s) isn't known. + * >= 0 index in table of given corrispondency. + * Precondintions: + * given pairs table MUST BE in code (frc, asr) order. + * pairs != NULL. + */ +static int match_ratio(const TCPair *pairs, size_t len, + int n, int d, int code) +{ + int i = 0, r = TC_NULL_MATCH; + for (i = 0; i < len; i++) { + if (i == code) { + r = i; + break; + } + if (n == pairs[i].a && d == pairs[i].b) { + r = i; + break; + } + } + return r; +} + +static int select_table(TCRatioCode rc, const TCPair **table, size_t *len) +{ + int ret = 0; + + switch (rc) { + case TC_FRC_CODE: + *table = frc_ratios; + *len = TABLE_LEN(frc_ratios); + break; + case TC_ASR_CODE: + *table = asr_ratios; + *len = TABLE_LEN(asr_ratios); + break; + case TC_PAR_CODE: + *table = par_ratios; + *len = TABLE_LEN(par_ratios); + break; + default: + *table = NULL; + *len = 0; + ret = TC_NULL_MATCH; + } + return ret; +} + +int tc_code_from_ratio(TCRatioCode rc, int *out_code, int in_n, int in_d) +{ + int code = TC_NULL_MATCH; + const TCPair *table = NULL; + size_t len = 0; + + select_table(rc, &table, &len); + if (table != NULL) { + code = match_ratio(table, len, in_n, in_d, TC_NULL_MATCH); + if (out_code != NULL && code != TC_NULL_MATCH) { + *out_code = code; + } + } + return code; +} + + +int tc_code_to_ratio(TCRatioCode rc, int in_code, int *out_n, int *out_d) +{ + int code = TC_NULL_MATCH; + const TCPair *table = NULL; + size_t len = 0; + + select_table(rc, &table, &len); + if (table != NULL) { + code = match_ratio(table, len, + TC_NULL_MATCH, TC_NULL_MATCH, in_code); + if ((out_n != NULL && out_d != NULL) && code != TC_NULL_MATCH) { + *out_n = table[code].a; + *out_d = table[code].b; + } + } + return code; +} + +/*************************************************************************/ + +/* + * Local variables: + * c-file-style: "stroustrup" + * c-file-offsets: ((case-label . *) (statement-case-intro . *)) + * indent-tabs-mode: nil + * End: + * + * vim: expandtab shiftwidth=4: + */ diff --git a/debian/transcode/transcode-1.1.7/libtc/ratiocodes.h b/debian/transcode/transcode-1.1.7/libtc/ratiocodes.h new file mode 100644 index 00000000..166c3014 --- /dev/null +++ b/debian/transcode/transcode-1.1.7/libtc/ratiocodes.h @@ -0,0 +1,193 @@ +/* + * ratiocodes.h -- database for all ratio/codes (asr, sar, dar, frc...) + * used in transcode + * (C) 2005-2010 - Francesco Romani <fromani -at- gmail -dot- com> + * + * This file is part of transcode, a video stream processing tool. + * + * transcode 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. + * + * transcode is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + + +#ifndef RATIOCODES_H +#define RATIOCODES_H + +/* + * same ratio codes (i.e.: code=3) have different meaning in + * different contexts, so we have this enum to let the + * tc_code_{from,to}_ratio functions distinguish operational + * context. + */ +typedef enum tccoderatio_ TCRatioCode; +enum tccoderatio_ { + TC_FRC_CODE = 1, /* frame ratio */ + TC_ASR_CODE, /* (display?) aspect ratio */ + TC_PAR_CODE, /* pixel aspect ratio */ +}; + +typedef struct tcpair_ TCPair; +struct tcpair_ { + int a; /* numerator, width... */ + int b; /* denominator, height... */ +}; + +#define TC_FRC_FPS_TO_RATIO(fps, pn, pd) \ +do { \ + *(pn) = (int)((fps) * 1000.0); \ + *(pd) = 1000; \ +} while(0) + +/* + * TCPair VS int/int dilemma: + * + * Why don't use out TCPair instead of int/int couples in + * functions interface below? + * this code (and the whole transcode in general) need to interact + * with a broad variety of foreign code with various conventions, + * interface, styles and so on. I've no *YET* found a clean way + * to use a custom struct (TCPair) for those situations without + * requiring to use a temporary variable, that looks quite + * clumsy to me. So I've chosen to fall back to minimum + * common denominator, that is a couple of int or pointer + * to ints. + * + * Of course this can change if a better and cleanest solution + * pops out :) + * + * BTW, TCPair is extensively used in internal processing and + * in private code. + */ + +/*************************************************************************/ + +/* + * tc_asr_code_describe: + * provides a descriptive, human readable string of given ASR code. + * + * Parameters: + * asr_code: the ASR code. + * Return Value: + * A constant string describing the given ASR code. + * There is NO NEED (and it is WRONG to do so) to free() it. + * Returned string is guaranteed to be valid at least until + * the next call to this function. + */ +const char *tc_asr_code_describe(int asr_code); + +/* + * tc_asr_code_from_value: + * detect the right aspect ratio code (asr) given an aspect ratio value + * as real number. + * + * Parameters: + * asr_code: pointer to integer where detected asr code will be stored. + * Can be NULL: if so, asr code will be detected but not + * stored. + * ratio: value of frame rate, as real number. + * Return Value: + * TC_NULL_MATCH if input value isn't known + * >= 0 otherwise + */ +int tc_asr_code_from_value(int *asr_code, double ratio); + +/* + * tc_frc_code_from_value: + * detect the right frame ratio code (frc) given a frame rate value as + * real number. + * + * Parameters: + * frc_code: pointer to integer where detected frc code will be stored. + * Can be NULL: if so, frc code will be detected but not + * stored. + * fps: value of frame rate, as real number. + * Return Value: + * TC_NULL_MATCH if input value isn't known + * >= 0 otherwise + */ +int tc_frc_code_from_value(int *frc_code, double fps); + +/* + * tc_frc_code_to_value: + * detect the right frame ratio value as real number given a frame rate + * code (frc). + * + * Parameters: + * frc_code: frame rate code. + * fps: pointer to double where detected frc value will be stored. + * Can be NULL: if so, frc value will be detected but not + * stored. + * Return Value: + * TC_NULL_MATCH if input value isn't known + * >= 0 otherwise + */ +int tc_frc_code_to_value(int frc_code, double *fps); + +/* + * tc_code_from_ratio: + * detect the right code in a specificied domain given a fraction as + * pair of integers. + * + * Parameters: + * rc: select operational domain. See definition of + * TCRatioCode above to see avalaible domains. + * code: pointer to integer where detected code will be stored. + * Can be NULL: if so, code will be detected but not + * stored. + * n: numerator of given frame ratio fraction. + * d: denominator of given frame ratio fraction. + * Return Value: + * TC_NULL_MATCH if input value isn't known + * >= 0 otherwise + */ +int tc_code_from_ratio(TCRatioCode rc, int *out_code, int in_n, int in_d); + +/* + * tc_frc_code_to_ratio: + * detect the right ratio fraction in a specified domain as pair of + * integers given a ratio code. + * + * Parameters: + * rc: select operational domain. See definition of + * TCRatioCode above to see avalaible domains. + * code: code to be converted in fraction. + * n: pointer to integer where numerator of rate fraction + * will ne stored. Can be NULL: if so, fraction will be + * detected but not stored. + * d: pointer to integer where denominator of frate fraction + * will ne stored. Can be NULL: if so, fraction will be + * detected but not stored. + * Return Value: + * TC_NULL_MATCH if input value isn't known + * >= 0 otherwise + */ +int tc_code_to_ratio(TCRatioCode rc, int in_code, int *out_n, int *out_d); + +/* macro goodies */ +#define tc_frc_code_from_ratio(frc, n, d) \ + tc_code_from_ratio(TC_FRC_CODE, frc, n, d) +#define tc_frc_code_to_ratio(frc, n, d) \ + tc_code_to_ratio(TC_FRC_CODE, frc, n, d) + +#define tc_asr_code_from_ratio(asr, n, d) \ + tc_code_from_ratio(TC_ASR_CODE, asr, n, d) +#define tc_asr_code_to_ratio(asr, n, d) \ + tc_code_to_ratio(TC_ASR_CODE, asr, n, d) + +#define tc_par_code_from_ratio(par, n, d) \ + tc_code_from_ratio(TC_PAR_CODE, par, n, d) +#define tc_par_code_to_ratio(par, n, d) \ + tc_code_to_ratio(TC_PAR_CODE, par, n, d) + + +#endif /* RATIOCODES_H */ diff --git a/debian/transcode/transcode-1.1.7/libtc/static_optstr.h b/debian/transcode/transcode-1.1.7/libtc/static_optstr.h new file mode 100644 index 00000000..627fed6c --- /dev/null +++ b/debian/transcode/transcode-1.1.7/libtc/static_optstr.h @@ -0,0 +1,23 @@ +/* + * static_optstr.h - static linkage helper for optstr. + * + * This file is part of transcode, a video stream processing tool. + * transcode is free software, distributable under the terms of the GNU + * General Public License (version 2 or later). See the file COPYING + * for details. + */ + +#ifndef STATIC_OPTSTR_H +#define STATIC_OPTSTR_H + +#include "libtc/optstr.h" +void dummy_optstr(void); +void dummy_optstr(void) { + optstr_lookup(NULL, NULL); + optstr_get(NULL, NULL, NULL); + optstr_filter_desc(NULL, NULL, NULL, NULL, NULL, NULL, NULL); + optstr_frames_needed(NULL, NULL); + optstr_param(NULL, NULL, NULL, NULL, NULL); +} + +#endif /* STATIC_OPTSTR_H */ diff --git a/debian/transcode/transcode-1.1.7/libtc/static_tclist.h b/debian/transcode/transcode-1.1.7/libtc/static_tclist.h new file mode 100644 index 00000000..60fb6ec9 --- /dev/null +++ b/debian/transcode/transcode-1.1.7/libtc/static_tclist.h @@ -0,0 +1,21 @@ +/* + * static_tclist.h - static linkage helper for tclist. + * + * This file is part of transcode, a video stream processing tool. + * transcode is free software, distributable under the terms of the GNU + * General Public License (version 2 or later). See the file COPYING + * for details. + */ + +#ifndef STATIC_TCLIST_H +#define STATIC_TCLIST_H + +#include "libtc/tclist.h" +void dummy_tclist(void); +void dummy_tclist(void) { + tc_list_init(NULL, 0); + tc_list_size(NULL); + tc_list_fini(NULL); +} + +#endif /* STATIC_TCLIST_H */ diff --git a/debian/transcode/transcode-1.1.7/libtc/static_tctimer.h b/debian/transcode/transcode-1.1.7/libtc/static_tctimer.h new file mode 100644 index 00000000..ace7c712 --- /dev/null +++ b/debian/transcode/transcode-1.1.7/libtc/static_tctimer.h @@ -0,0 +1,22 @@ +/* + * static_tctimer.h - static linkage helper for tctimer. + * + * This file is part of transcode, a video stream processing tool. + * transcode is free software, distributable under the terms of the GNU + * General Public License (version 2 or later). See the file COPYING + * for details. + */ + +#ifndef STATIC_TCTIMER_H +#define STATIC_TCTIMER_H + +#include "libtc/tctimer.h" +void dummy_tctimer(void); +void dummy_tctimer(void) { + TCTimer t; + + tc_timer_init_soft(&t, 0); + tc_timer_fini(&t); +} + +#endif /* STATIC_TCTIMER_H */ diff --git a/debian/transcode/transcode-1.1.7/libtc/static_xio.h b/debian/transcode/transcode-1.1.7/libtc/static_xio.h new file mode 100644 index 00000000..878b56a3 --- /dev/null +++ b/debian/transcode/transcode-1.1.7/libtc/static_xio.h @@ -0,0 +1,35 @@ +/* + * static_xio.h - static linkage helper for (lib)xio. + * + * This file is part of transcode, a video stream processing tool. + * transcode is free software, distributable under the terms of the GNU + * General Public License (version 2 or later). See the file COPYING + * for details. + */ + +#ifndef STATIC_XIO_H +#define STATIC_XIO_H + +#include "xio.h" +#include <fcntl.h> +#include <unistd.h> + +void dummy_xio(void); +void dummy_xio(void) +{ + int i; + struct stat tmp; + + i = xio_open("", O_RDONLY); + xio_read(i, NULL, 0); + xio_write(i, NULL, 0); + xio_ftruncate(i, 0); + xio_lseek(i, 0, 0); + xio_fstat(i, &tmp); + xio_lstat("", &tmp); + xio_stat("", &tmp); + xio_rename("", ""); + xio_close(i); +} + +#endif /* STATIC_XIO_H */ diff --git a/debian/transcode/transcode-1.1.7/libtc/strlcat.c b/debian/transcode/transcode-1.1.7/libtc/strlcat.c new file mode 100644 index 00000000..69da4f58 --- /dev/null +++ b/debian/transcode/transcode-1.1.7/libtc/strlcat.c @@ -0,0 +1,67 @@ +/* $OpenBSD: strlcat.c,v 1.12 2005/03/30 20:13:52 otto Exp $ */ + +/* + * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#if 0 +#if defined(LIBC_SCCS) && !defined(lint) +static char *rcsid = "$OpenBSD: strlcat.c,v 1.12 2005/03/30 20:13:52 otto Exp $"; +#endif /* LIBC_SCCS and not lint */ +#endif /* 0 */ + +#include "libtc.h" + +#ifndef HAVE_STRLCAT + +/* #include <sys/types.h> */ +/* #include <string.h> */ + +/* + * Appends src to string dst of size siz (unlike strncat, siz is the + * full size of dst, not space left). At most siz-1 characters + * will be copied. Always NUL terminates (unless siz <= strlen(dst)). + * Returns strlen(src) + MIN(siz, strlen(initial dst)). + * If retval >= siz, truncation occurred. + */ +size_t +strlcat(char *dst, const char *src, size_t siz) +{ + char *d = dst; + const char *s = src; + size_t n = siz; + size_t dlen; + + /* Find the end of dst and adjust bytes left but don't go past end */ + while (n-- != 0 && *d != '\0') + d++; + dlen = d - dst; + n = siz - dlen; + + if (n == 0) + return(dlen + strlen(s)); + while (*s != '\0') { + if (n != 1) { + *d++ = *s; + n--; + } + s++; + } + *d = '\0'; + + return(dlen + (s - src)); /* count does not include NUL */ +} + +#endif /* HAVE_STRLCAT */ diff --git a/debian/transcode/transcode-1.1.7/libtc/strlcpy.c b/debian/transcode/transcode-1.1.7/libtc/strlcpy.c new file mode 100644 index 00000000..1289afc5 --- /dev/null +++ b/debian/transcode/transcode-1.1.7/libtc/strlcpy.c @@ -0,0 +1,63 @@ +/* $OpenBSD: strlcpy.c,v 1.9 2005/03/30 20:13:52 otto Exp $ */ + +/* + * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#if 0 +#if defined(LIBC_SCCS) && !defined(lint) +static char *rcsid = "$OpenBSD: strlcpy.c,v 1.9 2005/03/30 20:13:52 otto Exp $"; +#endif /* LIBC_SCCS and not lint */ +#endif /* 0 */ + +#include "libtc.h" + +#ifndef HAVE_STRLCPY + +/* #include <sys/types.h> */ +/* #include <string.h> */ + +/* + * Copy src to string dst of size siz. At most siz-1 characters + * will be copied. Always NUL terminates (unless siz == 0). + * Returns strlen(src); if retval >= siz, truncation occurred. + */ +size_t +strlcpy(char *dst, const char *src, size_t siz) +{ + char *d = dst; + const char *s = src; + size_t n = siz; + + /* Copy as many bytes as will fit */ + if (n != 0 && --n != 0) { + do { + if ((*d++ = *s++) == 0) + break; + } while (--n != 0); + } + + /* Not enough room in dst, add NUL and traverse rest of src */ + if (n == 0) { + if (siz != 0) + *d = '\0'; /* NUL-terminate dst */ + while (*s++) + ; + } + + return(s - src - 1); /* count does not include NUL */ +} + +#endif /* HAVE_STRLCPY */ diff --git a/debian/transcode/transcode-1.1.7/libtc/tc_functions.c b/debian/transcode/transcode-1.1.7/libtc/tc_functions.c new file mode 100644 index 00000000..5c8b61d7 --- /dev/null +++ b/debian/transcode/transcode-1.1.7/libtc/tc_functions.c @@ -0,0 +1,923 @@ +/* + * tc_functions.c - various common functions for transcode + * Written by Thomas Oestreich, Francesco Romani, Andrew Church, and others + * + * This file is part of transcode, a video stream processing tool. + * transcode 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, or (at your option) + * any later version. + * + * transcode is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Make; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <string.h> +#include <stdlib.h> +#include <stdio.h> +#include <stdarg.h> +#include <unistd.h> +#include <errno.h> +#include <ctype.h> +#include <sys/stat.h> + +#include "xio.h" +#include "libtc.h" +#include "tc_defaults.h" + +#include "transcode.h" + +#include "ratiocodes.h" + +/*************************************************************************/ +#ifdef HAVE_FFMPEG + +pthread_mutex_t tc_libavcodec_mutex = PTHREAD_MUTEX_INITIALIZER; + +#endif +/*************************************************************************/ + +#define TC_MSG_BUF_SIZE (TC_BUF_MIN * 2) + +/* WARNING: we MUST keep in sync preambles order with TC_LOG* macros */ +static const char *tc_log_preambles[] = { + /* TC_LOG_ERR */ + "["COL_RED"%s"COL_GRAY"]"COL_RED" critical"COL_GRAY": %s\n", + /* TC_LOG_WARN */ + "["COL_RED"%s"COL_GRAY"]"COL_YELLOW" warning"COL_GRAY": %s\n", + /* TC_LOG_INFO */ + "["COL_BLUE"%s"COL_GRAY"] %s\n", + /* TC_LOG_MSG */ + "[%s] %s\n", + /* TC_LOG_EXTRA */ + "%s%s" /* tag placeholder must be present but tag will be ignored */ +}; + +static int tc_log_use_colors = TC_TRUE; +/* + * I'm not so proud of doing so. If someone has a better (cleaner) + * solution, just speak up. -- fromani 20060919 + */ + + +void libtc_init(int *argc, char ***argv) +{ + int ret = tc_mangle_cmdline(argc, argv, TC_LOG_COLOR_OPTION, NULL); + + if (ret == 0) { + tc_log_use_colors = TC_FALSE; + } else { + const char *envvar = getenv(TC_LOG_COLOR_ENV_VAR); + if (envvar != NULL) { + tc_log_use_colors = TC_FALSE; + } + } +} + + + +int tc_log(TCLogLevel level, const char *tag, const char *fmt, ...) +{ + char buf[TC_MSG_BUF_SIZE]; + char *msg = buf; + size_t size = sizeof(buf); + int dynbuf = TC_FALSE, truncated = TC_FALSE; + /* flag: we must use a dynamic (larger than static) buffer? */ + va_list ap; + + /* sanity check, avoid {under,over}flow; */ + level = (level < TC_LOG_ERR) ?TC_LOG_ERR :level; + level = (level > TC_LOG_EXTRA) ?TC_LOG_EXTRA :level; + /* sanity check, avoid dealing with NULL as much as we can */ + if (!tc_log_use_colors && level != TC_LOG_EXTRA) { + /* TC_LOG_EXTRA and TC_LOG_MSG must not use colors */ + level = TC_LOG_MSG; + } + + tag = (tag != NULL) ?tag :""; + fmt = (fmt != NULL) ?fmt :""; + /* TC_LOG_EXTRA special handling: force always empty tag */ + tag = (level == TC_LOG_EXTRA) ?"" :tag; + + size = strlen(tc_log_preambles[level]) + + strlen(tag) + strlen(fmt) + 1; + + if (size > sizeof(buf)) { + /* + * we use malloc/fprintf instead of tc_malloc because + * we want custom error messages + */ + msg = malloc(size); + if (msg != NULL) { + dynbuf = TC_TRUE; + } else { + fprintf(stderr, "(%s) CRITICAL: can't get memory in " + "tc_log() output will be truncated.\n", + __FILE__); + /* force reset to default values */ + msg = buf; + size = sizeof(buf) - 1; + truncated = TC_TRUE; + } + } else { + size = sizeof(buf) - 1; + } + + /* construct real format string */ + tc_snprintf(msg, size, tc_log_preambles[level], tag, fmt); +// msg[size] = '\0'; +// /* `size' value was already scaled for the final '\0' */ +// trusting valgrind, this assignement don't help us and can +// lead to troubles. So it's temporary disable until I gain +// some time to experiment -- fromani 20060919 + + va_start(ap, fmt); + vfprintf(stderr, msg, ap); + va_end(ap); + + if (dynbuf == 1) { + free(msg); + } + + /* ensure that all *other* messages are written */ + fflush(stderr); + return (truncated) ?-1 :0; +} + +/*************************************************************************/ + +int tc_mangle_cmdline(int *argc, char ***argv, + const char *opt, const char **optval) +{ + int i = 0, skew = (optval == NULL) ?1 :2, err = -1; + + if (argc == NULL || argv == NULL || opt == NULL) { + return err; + } + + err = 1; + /* first we looking for our option (and it's value) */ + for (i = 1; i < *argc; i++) { + if ((*argv)[i] && strcmp((*argv)[i], opt) == 0) { + if (optval == NULL) { + err = 0; /* we're set */ + } else { + /* don't peek after the end... */ + if (i + 1 >= *argc || (*argv)[i + 1][0] == '-') { + tc_log_warn(__FILE__, "wrong usage for option '%s'", opt); + err = 1; /* no option and/or value found */ + } else { + *optval = (*argv)[i + 1]; + err = 0; + } + } + break; + } + } + + /* + * if we've found our option, now we must shift back all + * the other options after the ours and we must also update argc. + */ + if (!err) { + for (; i < (*argc - skew); i++) { + (*argv)[i] = (*argv)[i + skew]; + } + (*argc) -= skew; + } + + return err; +} + + +int tc_test_program(const char *name) +{ +#ifndef NON_POSIX_PATH + const char *path = getenv("PATH"); + char *tok_path = NULL; + char *compl_path = NULL; + char *tmp_path; + char **strtokbuf; + char done; + size_t pathlen; + long sret; + int error = 0; + + if (name == NULL) { + tc_warn("ERROR: Searching for a NULL program!\n"); + return ENOENT; + } + + if (path == NULL) { + tc_warn("The '%s' program could not be found. \n", name); + tc_warn("Because your PATH environment variable is not set.\n"); + return ENOENT; + } + + pathlen = strlen(path) + 1; + tmp_path = tc_malloc(pathlen); + strtokbuf = tc_malloc(pathlen); + + sret = strlcpy(tmp_path, path, pathlen); + tc_test_string(__FILE__, __LINE__, pathlen, sret, errno); + + /* iterate through PATH tokens */ + for (done = 0, tok_path = strtok_r(tmp_path, ":", strtokbuf); + !done && tok_path; + tok_path = strtok_r((char *)0, ":", strtokbuf)) { + pathlen = strlen(tok_path) + strlen(name) + 2; + compl_path = tc_malloc(pathlen * sizeof(char)); + sret = tc_snprintf(compl_path, pathlen, "%s/%s", tok_path, name); + + if (access(compl_path, X_OK) == 0) { + error = 0; + done = 1; + } else { /* access != 0 */ + if (errno != ENOENT) { + done = 1; + error = errno; + } + } + + tc_free(compl_path); + } + + tc_free(tmp_path); + tc_free(strtokbuf); + + if (!done) { + tc_warn("The '%s' program could not be found. \n", name); + tc_warn("Please check your installation.\n"); + return ENOENT; + } + + if (error != 0) { + /* access returned an unhandled error */ + tc_warn("The '%s' program was found, but is not accessible.\n", name); + tc_warn("%s\n", strerror(errno)); + tc_warn("Please check your installation.\n"); + return error; + } +#endif + + return 0; +} + + +int tc_test_string(const char *file, int line, int limit, long ret, int errnum) +{ + if (ret < 0) { + fprintf(stderr, "[%s:%d] string error: %s\n", + file, line, strerror(errnum)); + return 1; + } + if (ret >= limit) { + fprintf(stderr, "[%s:%d] truncated %ld characters\n", + file, line, (ret - limit) + 1); + return 1; + } + return 0; +} + +/*************************************************************************/ + +/* + * These versions of [v]snprintf() return -1 if the string was truncated, + * printing a message to stderr in case of truncation (or other error). + */ + +int _tc_vsnprintf(const char *file, int line, char *buf, size_t limit, + const char *format, va_list args) +{ + int res = vsnprintf(buf, limit, format, args); + return tc_test_string(file, line, limit, res, errno) ? -1 : res; +} + + +int _tc_snprintf(const char *file, int line, char *buf, size_t limit, + const char *format, ...) +{ + va_list args; + int res; + + va_start(args, format); + res = _tc_vsnprintf(file, line, buf, limit, format, args); + va_end(args); + return res; +} + +/*************************************************************************/ + +/* simple malloc wrapper with failure guard. */ + +void *_tc_malloc(const char *file, int line, size_t size) +{ + void *p = malloc(size); + if (p == NULL) { + fprintf(stderr, "[%s:%d] tc_malloc(): can't allocate %lu bytes\n", + file, line, (unsigned long)size); + } + return p; +} + +/* allocate a chunk of memory (like tc_malloc), but zeroes memory before + * returning. */ + +void *_tc_zalloc(const char *file, int line, size_t size) +{ + void *p = malloc(size); + if (p == NULL) { + fprintf(stderr, "[%s:%d] tc_zalloc(): can't allocate %lu bytes\n", + file, line, (unsigned long)size); + } else { + memset(p, 0, size); + } + return p; +} + +/* realloc() wrapper. */ + +void *_tc_realloc(const char *file, int line, void *p, size_t size) +{ + p = realloc(p, size); + if (p == NULL && size > 0) { + fprintf(stderr, "[%s:%d] tc_realloc(): can't allocate %lu bytes\n", + file, line, (unsigned long)size); + } + return p; +} + + +/*** FIXME ***: find a clean way to refactorize above functions */ + +/* Allocate a buffer aligned to the machine's page size, if known. The + * buffer must be freed with buffree() (not free()). */ + +void *_tc_bufalloc(const char *file, int line, size_t size) +{ +#ifdef HAVE_GETPAGESIZE + unsigned long pagesize = getpagesize(); + int8_t *base = malloc(size + sizeof(void *) + pagesize); + int8_t *ptr = NULL; + unsigned long offset = 0; + + if (base == NULL) { + fprintf(stderr, "[%s:%d] tc_bufalloc(): can't allocate %lu bytes\n", + file, line, (unsigned long)size); + } else { + ptr = base + sizeof(void *); + offset = (unsigned long)ptr % pagesize; + + if (offset) + ptr += (pagesize - offset); + ((void **)ptr)[-1] = base; /* save the base pointer for freeing */ + } + return ptr; +#else /* !HAVE_GETPAGESIZE */ + return malloc(size); +#endif +} + +char *_tc_strndup(const char *file, int line, const char *s, size_t n) +{ + char *pc = NULL; + + if (s != NULL) { + pc = _tc_malloc(file, line, n + 1); + if (pc != NULL) { + memcpy(pc, s, n); + pc[n] = '\0'; + } + } + return pc; +} + +/* Free a buffer allocated with tc_bufalloc(). */ +void tc_buffree(void *ptr) +{ +#ifdef HAVE_GETPAGESIZE + if (ptr) + free(((void **)ptr)[-1]); +#else + free(ptr); +#endif +} + +/*************************************************************************/ + +ssize_t tc_pread(int fd, uint8_t *buf, size_t len) +{ + ssize_t n = 0; + ssize_t r = 0; + + while (r < len) { + n = xio_read(fd, buf + r, len - r); + + if (n == 0) { /* EOF */ + break; + } + if (n < 0) { + if (errno == EINTR) { + continue; + } else { + break; + } + } + r += n; + } + return r; +} + + +ssize_t tc_pwrite(int fd, const uint8_t *buf, size_t len) +{ + ssize_t n = 0; + ssize_t r = 0; + + while (r < len) { + n = xio_write(fd, buf + r, len - r); + + if (n < 0) { + if (errno == EINTR) { + continue; + } else { + break; + } + } + r += n; + } + return r; +} + +#ifdef PIPE_BUF +# define BLOCKSIZE PIPE_BUF /* 4096 on linux-x86 */ +#else +# define BLOCKSIZE 4096 +#endif + +int tc_preadwrite(int fd_in, int fd_out) +{ + uint8_t buffer[BLOCKSIZE]; + ssize_t bytes; + int error = 0; + + do { + bytes = tc_pread(fd_in, buffer, BLOCKSIZE); + + /* error on read? */ + if (bytes < 0) { + return -1; + } + + /* read stream end? */ + if (bytes != BLOCKSIZE) { + error = 1; + } + + if (bytes) { + /* write stream problems? */ + if (tc_pwrite(fd_out, buffer, bytes) != bytes) { + error = 1; + } + } + } while (!error); + + return 0; +} + +int tc_file_check(const char *name) +{ + struct stat fbuf; + + if(xio_stat(name, &fbuf)) { + tc_log_warn(__FILE__, "invalid file \"%s\"", name); + return -1; + } + + /* file or directory? */ + if(S_ISDIR(fbuf.st_mode)) { + return 1; + } + return 0; +} + +#ifndef major +# define major(dev) (((dev) >> 8) & 0xff) +#endif + +int tc_probe_path(const char *name) +{ + struct stat fbuf; + + if(name == NULL) { + tc_log_warn(__FILE__, "invalid file \"%s\"", name); + return TC_PROBE_PATH_INVALID; + } + + if(xio_stat(name, &fbuf) == 0) { + /* inode exists */ + + /* treat DVD device as absolute directory path */ + if (S_ISBLK(fbuf.st_mode)) { + return TC_PROBE_PATH_ABSPATH; + } + + /* char device could be several things, depending on system */ + /* *BSD DVD device? v4l? bktr? sunau? */ + if(S_ISCHR(fbuf.st_mode)) { + switch (major(fbuf.st_rdev)) { +#ifdef OS_BSD +# ifdef __OpenBSD__ + case 15: /* rcd */ + return TC_PROBE_PATH_ABSPATH; + case 42: /* sunau */ + return TC_PROBE_PATH_SUNAU; + case 49: /* bktr */ + return TC_PROBE_PATH_BKTR; +# endif +# ifdef __FreeBSD__ + case 4: /* acd */ + return TC_PROBE_PATH_ABSPATH; + case 229: /* bktr */ + return TC_PROBE_PATH_BKTR; + case 0: /* OSS */ + return TC_PROBE_PATH_OSS; +# endif + default: /* libdvdread uses "raw" disk devices here */ + return TC_PROBE_PATH_ABSPATH; +#else + case 81: /* v4l (Linux) */ + return TC_PROBE_PATH_V4L_VIDEO; + case 14: /* OSS */ + return TC_PROBE_PATH_OSS; + default: + break; +#endif + } + } + + /* file or directory? */ + if (!S_ISDIR(fbuf.st_mode)) { + return TC_PROBE_PATH_FILE; + } + + /* directory, check for absolute path */ + if(name[0] == '/') { + return TC_PROBE_PATH_ABSPATH; + } + + /* directory mode */ + return TC_PROBE_PATH_RELDIR; + } else { + tc_log_warn(__FILE__, "invalid filename \"%s\"", name); + return TC_PROBE_PATH_INVALID; + } + + return TC_PROBE_PATH_INVALID; +} + +/*************************************************************************/ + +#define RESIZE_DIV 8 +#define DIM_IS_OK(dim) ((dim) % RESIZE_DIV == 0) + +int tc_compute_fast_resize_values(void *_vob, int strict) +{ + int ret = -1; + int dw = 0, dh = 0; /* delta width, height */ + vob_t *vob = _vob; /* adjust pointer */ + + /* sanity checks first */ + if (vob == NULL) { + return -1; + } + if (!DIM_IS_OK(vob->ex_v_width) || !DIM_IS_OK(vob->ex_v_width)) { + return -1; + } + if (!DIM_IS_OK(vob->zoom_width) || !DIM_IS_OK(vob->zoom_width)) { + return -1; + } + + dw = vob->ex_v_width - vob->zoom_width; + dh = vob->ex_v_height - vob->zoom_height; + /* MORE sanity checks */ + if (!DIM_IS_OK(dw) || !DIM_IS_OK(dh)) { + return -1; + } + if (dw == 0 && dh == 0) { + /* we're already fine */ + ret = 0; + } else if (dw > 0 && dh > 0) { + /* smaller destination frame -> -B */ + vob->resize1_mult = RESIZE_DIV; + vob->hori_resize1 = dw / RESIZE_DIV; + vob->vert_resize1 = dh / RESIZE_DIV; + ret = 0; + } else if (dw < 0 && dh < 0) { + /* bigger destination frame -> -X */ + vob->resize2_mult = RESIZE_DIV; + vob->hori_resize2 = -dw / RESIZE_DIV; + vob->vert_resize2 = -dh / RESIZE_DIV; + ret = 0; + } else if (strict == 0) { + /* always needed in following cases */ + vob->resize1_mult = RESIZE_DIV; + vob->resize2_mult = RESIZE_DIV; + ret = 0; + if (dw <= 0 && dh >= 0) { + vob->hori_resize2 = -dw / RESIZE_DIV; + vob->vert_resize1 = dh / RESIZE_DIV; + } else if (dw >= 0 && dh <= 0) { + vob->hori_resize1 = dw / RESIZE_DIV; + vob->vert_resize2 = -dh / RESIZE_DIV; + } + } + + if (ret == 0) { + vob->zoom_width = 0; + vob->zoom_height = 0; + } + return ret; +} + +#undef RESIZE_DIV +#undef DIM_IS_OK + +/*************************************************************************/ + + +int tc_find_best_aspect_ratio(const void *_vob, + int *sar_num, int *sar_den, + const char *tag) +{ + const vob_t *vob = _vob; /* adjust pointer */ + int num, den; + + if (!vob || !sar_num || !sar_den) { + return TC_ERROR; + } + + /* Aspect Ratio Calculations (modified code from export_ffmpeg.c) */ + if (vob->export_attributes & TC_EXPORT_ATTRIBUTE_PAR) { + if (vob->ex_par > 0) { + /* + * vob->ex_par MUST be guarantee to be in a sane range + * by core (transcode/tcexport + */ + tc_par_code_to_ratio(vob->ex_par, &num, &den); + } else { + /* same as above */ + num = vob->ex_par_width; + den = vob->ex_par_height; + } + tc_log_info(tag, "DAR value ratio calculated as %f = %d/%d", + (double)num/(double)den, num, den); + } else { + if (vob->export_attributes & TC_EXPORT_ATTRIBUTE_ASR) { + /* same as above for PAR stuff */ + tc_asr_code_to_ratio(vob->ex_asr, &num, &den); + tc_log_info(tag, "display aspect ratio calculated as %f = %d/%d", + (double)num/(double)den, num, den); + + /* ffmpeg FIXME: + * This original code might lead to rounding/truncating errors + * and maybe produces too high values for "den" and + * "num" for -y ffmpeg -F mpeg4 + * + * sar = dar * ((double)vob->ex_v_height / (double)vob->ex_v_width); + * lavc_venc_context->sample_aspect_ratio.num = (int)(sar * 1000); + * lavc_venc_context->sample_aspect_ratio.den = 1000; + */ + + num *= vob->ex_v_height; + den *= vob->ex_v_width; + /* I don't need to reduce since x264 does it itself :-) */ + tc_log_info(tag, "sample aspect ratio calculated as" + " %f = %d/%d", + (double)num/(double)den, num, den); + + } else { /* user did not specify asr at all, assume no change */ + tc_log_info(tag, "set display aspect ratio to input"); + num = 1; + den = 1; + } + } + + *sar_num = num; + *sar_den = den; + return TC_OK; +} + +/*************************************************************************/ + +void tc_strstrip(char *s) +{ + char *start; + + if (s == NULL) { + return; + } + + start = s; + while ((*start != 0) && isspace(*start)) { + start++; + } + + memmove(s, start, strlen(start) + 1); + if (strlen(s) == 0) { + return; + } + + start = &s[strlen(s) - 1]; + while ((start != s) && isspace(*start)) { + *start = 0; + start--; + } +} + +char **tc_strsplit(const char *str, char sep, size_t *pieces_num) +{ + const char *begin = str, *end = NULL; + char **pieces = NULL, *pc = NULL; + size_t i = 0, n = 2; + int failed = TC_FALSE; + + if (!str || !strlen(str)) { + return NULL; + } + + while (begin != NULL) { + begin = strchr(begin, sep); + if (begin != NULL) { + begin++; + n++; + } + } + + pieces = tc_malloc(n * sizeof(char*)); + if (!pieces) { + return NULL; + } + + begin = str; + while (begin != NULL) { + size_t len; + + end = strchr(begin, sep); + if (end != NULL) { + len = (end - begin); + } else { + len = strlen(begin); + } + if (len > 0) { + pc = tc_strndup(begin, len); + if (pc == NULL) { + failed = TC_TRUE; + break; + } else { + pieces[i] = pc; + i++; + } + } + if (end != NULL) { + begin = end + 1; + } else { + break; + } + } + + if (failed) { + /* one or more copy of pieces failed */ + tc_free(pieces); + pieces = NULL; + } else { /* i == n - 1 -> all pieces copied */ + pieces[n - 1] = NULL; /* end marker */ + if (pieces_num != NULL) { + *pieces_num = i; + } + } + return pieces; +} + +void tc_strfreev(char **pieces) +{ + if (pieces != NULL) { + int i = 0; + for (i = 0; pieces[i] != NULL; i++) { + tc_free(pieces[i]); + } + tc_free(pieces); + } +} + +/*************************************************************************/ + +/* + * clamp an unsigned value so it can be safely (without any loss) in + * an another unsigned integer of <butsize> bits. + */ +static int32_t clamp(int32_t value, uint8_t bitsize) +{ + value = (value < 1) ?1 :value; + value = (value > (1 << bitsize)) ?(1 << bitsize) :value; + return value; +} + +int tc_read_matrix(const char *filename, uint8_t *m8, uint16_t *m16) +{ + int i = 0; + FILE *input = NULL; + + /* Open the matrix file */ + input = fopen(filename, "rb"); + if (!input) { + tc_log_warn("read_matrix", + "Error opening the matrix file %s", + filename); + return -1; + } + if (!m8 && !m16) { + tc_log_warn("read_matrix", "bad matrix reference"); + return -1; + } + + /* Read the matrix */ + for(i = 0; i < TC_MATRIX_SIZE; i++) { + int value; + + /* If fscanf fails then get out of the loop */ + if(fscanf(input, "%d", &value) != 1) { + tc_log_warn("read_matrix", + "Error reading the matrix file %s", + filename); + fclose(input); + return 1; + } + + if (m8 != NULL) { + m8[i] = clamp(value, 8); + } else { + m16[i] = clamp(value, 16); + } + } + + /* We're done */ + fclose(input); + + return 0; +} + +void tc_print_matrix(uint8_t *m8, uint16_t *m16) +{ + int i; + + if (!m8 && !m16) { + tc_log_warn("print_matrix", "bad matrix reference"); + return; + } + + // XXX: magic number + for(i = 0; i < TC_MATRIX_SIZE; i += 8) { + if (m8 != NULL) { + tc_log_info("print_matrix", + "%3d %3d %3d %3d " + "%3d %3d %3d %3d", + (int)m8[i ], (int)m8[i+1], + (int)m8[i+2], (int)m8[i+3], + (int)m8[i+4], (int)m8[i+5], + (int)m8[i+6], (int)m8[i+7]); + } else { + tc_log_info("print_matrix", + "%3d %3d %3d %3d " + "%3d %3d %3d %3d", + (int)m16[i ], (int)m16[i+1], + (int)m16[i+2], (int)m16[i+3], + (int)m16[i+4], (int)m16[i+5], + (int)m16[i+6], (int)m16[i+7]); + } + } + return; +} + +/*************************************************************************/ + +/* + * Local variables: + * c-file-style: "stroustrup" + * c-file-offsets: ((case-label . *) (statement-case-intro . *)) + * indent-tabs-mode: nil + * End: + * + * vim: expandtab shiftwidth=4: + */ diff --git a/debian/transcode/transcode-1.1.7/libtc/tc_lzo.h b/debian/transcode/transcode-1.1.7/libtc/tc_lzo.h new file mode 100644 index 00000000..b6eaf5ce --- /dev/null +++ b/debian/transcode/transcode-1.1.7/libtc/tc_lzo.h @@ -0,0 +1,49 @@ +/* + * tc_lzo.h - LZO extra (meta) data used by transcode + * + * This file is part of transcode, a video stream processing tool. + * transcode is free software, distributable under the terms of the GNU + * General Public License (version 2 or later). See the file COPYING + * for details. + */ + +#ifndef TC_LZO_H +#define TC_LZO_H + +#include <lzo/lzo1x.h> +#include <lzo/lzoutil.h> + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <stdint.h> +#include <sys/types.h> + +/* flags */ +#define TC_LZO_FORMAT_YV12 1 /* obsolete */ +#define TC_LZO_FORMAT_RGB24 2 +#define TC_LZO_FORMAT_YUY2 4 +#define TC_LZO_NOT_COMPRESSIBLE 8 +#define TC_LZO_FORMAT_YUV420P 16 + +#define TC_LZO_HDR_SIZE 16 +/* + * bytes; sum of sizes of tc_lzo_header_t members; + * _can_ be different from sizeof(tc_lzo_header_t) + * because structure can be padded (even if it's unlikely + * since it's already 32-bit and 64-bit aligned). + * I don't like __attribute__(packed). + */ + +typedef struct tc_lzo_header_t { + uint32_t magic; + uint32_t size; + uint32_t flags; + uint8_t method; /* compression method */ + uint8_t level; /* compression level */ + uint16_t pad; +} tc_lzo_header_t; + + +#endif /* TC_LZO_H */ diff --git a/debian/transcode/transcode-1.1.7/libtc/tcavcodec.h b/debian/transcode/transcode-1.1.7/libtc/tcavcodec.h new file mode 100644 index 00000000..baf88893 --- /dev/null +++ b/debian/transcode/transcode-1.1.7/libtc/tcavcodec.h @@ -0,0 +1,63 @@ +/* + * tcavcodec.h -- transcode's support macros and tools for easier + * libavcodec/libavformat/libavutil usage + * (C) 2007-2010 - Francesco Romani <fromani at gmail dot com> + * + * This file is part of transcode, a video stream processing tool. + * + * transcode 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. + * + * transcode is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + + +#ifndef TCAVCODEC_H +#define TCAVCODEC_H + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <pthread.h> + +#include <libavutil/avutil.h> +#include <libavcodec/avcodec.h> +#include <libavformat/avformat.h> + +/*************************************************************************/ + +/* + * libavcodec lock. Used for serializing initialization/open of library. + * Other libavcodec routines (avcodec_{encode,decode}_* should be thread + * safe (as ffmpeg crew said) if each thread uses it;s own AVCodecContext, + * as we do. + */ +extern pthread_mutex_t tc_libavcodec_mutex; + +/* + * libavcodec locking goodies. It's preferred and encouraged to use + * macros below, but accessing libavcodec mutex will work too. + */ +#define TC_LOCK_LIBAVCODEC (pthread_mutex_lock(&tc_libavcodec_mutex)) +#define TC_UNLOCK_LIBAVCODEC (pthread_mutex_unlock(&tc_libavcodec_mutex)) + + +#define TC_INIT_LIBAVCODEC do { \ + TC_LOCK_LIBAVCODEC; \ + avcodec_init(); \ + avcodec_register_all(); \ + TC_UNLOCK_LIBAVCODEC; \ +} while (0) + + +#endif /* TCAVCODEC_H */ + diff --git a/debian/transcode/transcode-1.1.7/libtc/tccodecs.c b/debian/transcode/transcode-1.1.7/libtc/tccodecs.c new file mode 100644 index 00000000..35aafa07 --- /dev/null +++ b/debian/transcode/transcode-1.1.7/libtc/tccodecs.c @@ -0,0 +1,346 @@ +/* + * tccodecs.c -- codecs helper functions. + * (C) 2005-2010 - Francesco Romani <fromani -at- gmail -dot- com> + * + * This file is part of transcode, a video stream processing tool. + * + * transcode 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. + * + * transcode is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + + +#include "libtc.h" +#include "src/transcode.h" +#include "tccodecs.h" + +#include <string.h> + +/* internal usage only ***************************************************/ + +typedef struct { + TCCodecID id; /* a TC_CODEC_* value */ + const char *name; /* usually != fourcc */ + const char *fourcc; /* real-world fourcc */ + const char *comment; + int multipass; /* multipass capable */ + int flags; +} TCCodecInfo; + + +/* + * this table is *always* accessed in RO mode, so there is no need + * to protect it with threading locks + */ +static const TCCodecInfo tc_codecs_info[] = { + /* video codecs */ + { TC_CODEC_RGB, "rgb", "RGB", + "RGB/BGR", 0, TC_VIDEO }, + { TC_CODEC_YUV420P, "yuv420p", "I420", + "YUV420P", 0, TC_VIDEO }, + { TC_CODEC_YUV422P, "yuv422p", "UYVY", + "YUV422P", 0, TC_VIDEO }, + { TC_CODEC_YUY2, "yuy2", "YUY2", + "YUY2", 0, TC_VIDEO }, + // XXX: right fcc? + { TC_CODEC_MPEG1VIDEO, "mpeg1video", "mpg1", + "MPEG1 ES", 1, TC_VIDEO }, + { TC_CODEC_MPEG2VIDEO, "mpeg2video", "mpg2", + "MPEG2 ES", 1, TC_VIDEO }, + { TC_CODEC_MPEG4VIDEO, "mpeg4video", "mp4v", + "MPEG4 ES", 1, TC_VIDEO }, + /* FIXME; set up `DIVX' fcc for backward compatibility? */ + { TC_CODEC_XVID, "xvid", "XVID", + "XviD", 1, TC_VIDEO }, + { TC_CODEC_DIVX3, "divx3", "DIV3", + "DivX;-)", 1, TC_VIDEO }, + { TC_CODEC_DIVX4, "divx4", "DIVX", + "DivX 4.x", 1, TC_VIDEO }, + { TC_CODEC_DIVX5, "divx5", "DX50", + "DivX 5.x", 1, TC_VIDEO }, + { TC_CODEC_MJPEG, "mjpeg", "MJPG", + "MJPEG", 0, TC_VIDEO }, + { TC_CODEC_LJPEG, "ljpeg", "LJPG", + "Lossless (motion) JPEG", 0, TC_VIDEO }, + { TC_CODEC_DV, "dvvideo", "DVSD", + "DigitalVideo", 0, TC_VIDEO }, + { TC_CODEC_LZO1, "lzo1", "LZO1", + "LZO v1", 0, TC_VIDEO }, + { TC_CODEC_LZO2, "lzo2", "LZO2", + "LZO v2", 0, TC_VIDEO }, + { TC_CODEC_MP42, "msmpeg4v2", "MP42", + "MS MPEG4 v2", 1, TC_VIDEO }, + { TC_CODEC_MP43, "msmpeg4v3", "MP43", + "MS MPEG4 v3", 1, TC_VIDEO }, + { TC_CODEC_RV10, "realvideo10", "RV10", + "RealVideo (old)", 0, TC_VIDEO }, + { TC_CODEC_WMV1, "wmv1", "WMV1", + "WMV v1 (WMP7)", 1, TC_VIDEO }, + { TC_CODEC_WMV2, "wmv2", "WMV2", + "WMV v2 (WMP8)", 1, TC_VIDEO }, + { TC_CODEC_H264, "h264", "H264", + "h.264 (AVC)", 1, TC_VIDEO }, + { TC_CODEC_H263P, "h263p", "H263", + "h.263 plus", 1, TC_VIDEO }, + // XXX: right fcc? + { TC_CODEC_H263I, "h263", "H263", + "h.263", 0, TC_VIDEO }, + + { TC_CODEC_HUFFYUV, "huffyuv", "HFYU", + "HuffYUV", 1, TC_VIDEO }, + // XXX: right fcc? + { TC_CODEC_FFV1, "ffv1", "FFV1", + "FFV1 (experimental)", 1, TC_VIDEO }, + { TC_CODEC_ASV1, "asusvideo1", "ASV1", + "ASUS codec v1", 0, TC_VIDEO }, + { TC_CODEC_ASV2, "asusvideo2", "ASV2", + "ASUS codec v2", 0, TC_VIDEO }, + { TC_CODEC_PV3, "pv3", "PV3", + "PV3", 0, TC_VIDEO }, /* XXX */ + { TC_CODEC_NUV, "nuv", "NUV", + "RTjpeg", 0, TC_VIDEO }, /* XXX */ + + /* FIXME: add more codec informations, on demand */ + + /* audio codecs */ + { TC_CODEC_PCM, "pcm", NULL, + "PCM", 0, TC_AUDIO }, + { TC_CODEC_LPCM, "lpcm", NULL, + "LPCM", 0, TC_AUDIO }, + { TC_CODEC_AC3, "ac3", NULL, + "AC3", 0, TC_AUDIO }, + { TC_CODEC_MP3, "mp3", NULL, + "MPEG ES Layer 3", 0, TC_AUDIO }, + { TC_CODEC_MP2, "mp2", NULL, + "MPEG ES Layer 2", 0, TC_AUDIO }, + { TC_CODEC_AAC, "aac", NULL, + "AAC", 0, TC_AUDIO }, + { TC_CODEC_VORBIS, "vorbis", NULL, + "ogg/vorbis", 0, TC_AUDIO }, + { TC_CODEC_VAG, "vag", NULL, + "PS-VAG", 0, TC_AUDIO }, + /* FIXME: add more codec informations, on demand */ + + /* miscelanous; XXX: drop from here */ + { TC_CODEC_MPEG, "MPEG", NULL, + "MPEG program stream", 0, TC_VIDEO|TC_AUDIO }, + { TC_CODEC_MPEG1, "MPEG-1", NULL, + "MPEG 1 program stream", 0, TC_VIDEO|TC_AUDIO }, + { TC_CODEC_MPEG2, "MPEG-2", NULL, + "MPEG 2 program stream", 0, TC_VIDEO|TC_AUDIO }, + + /* special codecs*/ + { TC_CODEC_ANY, "everything", NULL, + NULL, 0, 0 }, + { TC_CODEC_UNKNOWN, "unknown", NULL, + NULL, 0, 0 }, + { TC_CODEC_ERROR, "error", NULL, + NULL, 0, 0 }, // XXX + /* this MUST be the last one */ +}; + +/* compatibility */ +int tc_translate_codec_id(TCCodecID codec) +{ + switch (codec) { + case CODEC_AC3: return TC_CODEC_AC3; + case CODEC_MP3: return TC_CODEC_MP3; + case CODEC_MP2: return TC_CODEC_MP2; + case CODEC_PCM: return TC_CODEC_PCM; + case CODEC_LPCM: return TC_CODEC_LPCM; + case CODEC_VORBIS: return TC_CODEC_VORBIS; + case CODEC_VAG: return TC_CODEC_VAG; + default: return TC_CODEC_ERROR; /* can't happen */ + } + return TC_CODEC_ERROR; +} + + +/* + * TCCodecMatcher: + * generic codec finder function family. + * tell if a TCCodecInfo descriptor match certains given criterias + * using a function-dependent method. + * See also 'find_tc_codec' function. + * + * Parameters: + * info: a pointer to a TCCodecInfo descriptor to be examinated + * userdata: a pointer to data with function-dependent meaning + * Return Value: + * TC_TRUE if function succeed, + * TC_FALSE otherwise. + */ +typedef int (*TCCodecMatcher)(const TCCodecInfo *info, const void *userdata); + +/* + * id_matcher: + * match a TCCodecInfo descriptor on codec's id. + * 'userdata' must be an *address* of an uint32_t containing a TC_CODEC_* + * to match. + * + * Parameters: + * as for TCCodecMatcher + * Return Value: + * as for TCCodecMatcher + */ +static int id_matcher(const TCCodecInfo *info, const void *userdata) +{ + if (info == NULL || userdata == NULL) { + return TC_FALSE; + } + + return (*(int*)userdata == info->id) ?TC_TRUE :TC_FALSE; +} + +/* + * name_matcher: + * match a TCCodecInfo descriptor on codec's name (note: note != fourcc). + * 'userdata' must be the C-string to match. + * Note: ignore case. + * + * Parameters: + * as for TCCodecMatcher + * Return Value: + * as for TCCodecMatcher + */ +static int name_matcher(const TCCodecInfo *info, const void *userdata) +{ + if (info == NULL || userdata == NULL) { + return TC_FALSE; + } + if(!info->name || (strcasecmp(info->name, userdata) != 0)) { + return TC_FALSE; + } + return TC_TRUE; +} + +/* + * find_tc_codec: + * find a TCCodecInfo descriptor matching certains given criterias. + * It scans the whole TCCodecInfos table applying the given + * matcher with the given data to each element, halting when a match + * is found + * + * Parameters: + * matcher: a TCCodecMatcher to be applied to find the descriptor. + * userdata: matching data to be passed to matcher together with a table + * entry. + * + * Return Value: + * >= 0: index of an entry in TCCodecInfo in table if an entry match + * the finding criteria + * TC_NULL_MATCH if no entry matches the given criteria + */ +static int find_tc_codec(const TCCodecInfo *infos, + TCCodecMatcher matcher, + const void *userdata) +{ + int found = TC_FALSE, i = 0; + + if (infos == NULL) { + return TC_NULL_MATCH; + } + + for (i = 0; infos[i].id != TC_CODEC_ERROR; i++) { + found = matcher(&infos[i], userdata); + if (found) { + break; + } + } + if (!found) { + i = TC_NULL_MATCH; + } + + return i; +} + +/* public API ************************************************************/ + +const char* tc_codec_to_comment(TCCodecID codec) +{ + int idx = find_tc_codec(tc_codecs_info, id_matcher, &codec); + + if (idx == TC_NULL_MATCH) { /* not found */ + return "unknown"; + } + return tc_codecs_info[idx].comment; /* can be NULL */ +} + + +const char* tc_codec_to_string(TCCodecID codec) +{ + int idx = find_tc_codec(tc_codecs_info, id_matcher, &codec); + + if (idx == TC_NULL_MATCH) { /* not found */ + return NULL; + } + return tc_codecs_info[idx].name; /* can be NULL */ +} + +TCCodecID tc_codec_from_string(const char *codec) +{ + int idx = find_tc_codec(tc_codecs_info, name_matcher, codec); + + if (idx == TC_NULL_MATCH) { /* not found */ + return TC_CODEC_ERROR; + } + return tc_codecs_info[idx].id; +} + +const char* tc_codec_fourcc(TCCodecID codec) +{ + int idx = find_tc_codec(tc_codecs_info, id_matcher, &codec); + + if (idx == TC_NULL_MATCH) { /* not found */ + return NULL; + } + return tc_codecs_info[idx].fourcc; /* can be NULL */ +} + +int tc_codec_description(TCCodecID codec, char *buf, size_t bufsize) +{ + int idx = find_tc_codec(tc_codecs_info, id_matcher, &codec); + int ret; + + if (idx == TC_NULL_MATCH) { /* not found */ + return -1; + } + + ret = tc_snprintf(buf, bufsize, "%-12s: (fourcc=%s multipass=%-3s) %s", + tc_codecs_info[idx].name, + tc_codecs_info[idx].fourcc, + tc_codecs_info[idx].multipass ?"yes" :"no", + tc_codecs_info[idx].comment); + return ret; +} + +int tc_codec_is_multipass(TCCodecID codec) +{ + int idx = find_tc_codec(tc_codecs_info, id_matcher, &codec); + + if (idx == TC_NULL_MATCH) { /* not found */ + return TC_FALSE; + } + return tc_codecs_info[idx].multipass; +} + +/*************************************************************************/ + +/* + * Local variables: + * c-file-style: "stroustrup" + * c-file-offsets: ((case-label . *) (statement-case-intro . *)) + * indent-tabs-mode: nil + * End: + * + * vim: expandtab shiftwidth=4: + */ diff --git a/debian/transcode/transcode-1.1.7/libtc/tccodecs.h b/debian/transcode/transcode-1.1.7/libtc/tccodecs.h new file mode 100644 index 00000000..cd288d79 --- /dev/null +++ b/debian/transcode/transcode-1.1.7/libtc/tccodecs.h @@ -0,0 +1,109 @@ +/* + * tccodecs.h + * + * Copyright (C) Thomas Oestreich - June 2001 + * ripped from 'magic.h' by Francesco Romani - November 2005 + * + * This file is part of transcode, a video stream processing tool + * + * transcode 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, or (at your option) + * any later version. + * + * transcode is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Make; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#ifndef TC_CODECS_H +#define TC_CODECS_H + +/* + * codecs identifiers. + * (WARNING: avilib relies on these _values_, at least for audio) + */ + +typedef enum { + /* ok, now the real codecs */ + TC_CODEC_PCM = 0x00000001, + TC_CODEC_LPCM = 0x00010001, + + TC_CODEC_AC3 = 0x00002000, + TC_CODEC_DTS = 0x0001000f, + TC_CODEC_MP3 = 0x00000055, + TC_CODEC_MP2 = 0x00000050, + TC_CODEC_AAC = 0x000000FF, + TC_CODEC_VORBIS = 0x0000FFFE, + + /* we need special values here? */ + TC_CODEC_RGB = 0x00000024, + TC_CODEC_YV12 = 0x32315659, + TC_CODEC_YUV420P = 0x30323449, + TC_CODEC_YUV422P = 0x42323459, + TC_CODEC_UYVY = 0x59565955, + TC_CODEC_YUV2 = 0x32565559, + TC_CODEC_YUY2 = 0x32595559, + + /* this group should be probably removed or changed */ + TC_CODEC_M2V = 0x000001b3, + TC_CODEC_MPEG = 0x01000000, + TC_CODEC_MPEG1 = 0x00100000, + TC_CODEC_MPEG2 = 0x00010000, + TC_CODEC_PS1 = 0x00007001, + TC_CODEC_PS2 = 0x00007002, + TC_CODEC_SUB = 0xA0000011, + + /* we really need a specific value for those? */ + TC_CODEC_DV = 0x00001000, + TC_CODEC_VAG = 0x0000FEED, + TC_CODEC_PV3 = 0x50563301, + /* no special meaning, just enumeration from here */ + TC_CODEC_DIVX3 = 0xFFFE0001, + TC_CODEC_MP42, + TC_CODEC_MP43, + TC_CODEC_DIVX4, + TC_CODEC_DIVX5, + TC_CODEC_XVID, + TC_CODEC_H264, + TC_CODEC_MJPEG, + TC_CODEC_MPG1, + TC_CODEC_NUV, + TC_CODEC_LZO1, + TC_CODEC_RV10, + TC_CODEC_SVQ1, + TC_CODEC_SVQ3, + TC_CODEC_VP3, + TC_CODEC_4XM, + TC_CODEC_WMV1, + TC_CODEC_WMV2, + TC_CODEC_HUFFYUV, + TC_CODEC_INDEO3, + TC_CODEC_H263P, + TC_CODEC_H263I, + TC_CODEC_LZO2, + TC_CODEC_FRAPS, + TC_CODEC_FFV1, + TC_CODEC_ASV1, + TC_CODEC_ASV2, + TC_CODEC_THEORA, + TC_CODEC_MPEG1VIDEO, + TC_CODEC_MPEG2VIDEO, + TC_CODEC_MPEG4VIDEO, + TC_CODEC_LJPEG, /* lossless (motion) JPEG */ + + /* special (pseudo)codecs */ + TC_CODEC_UNKNOWN = 0x00000000, + TC_CODEC_RAW = 0xFEFEFEFE, + TC_CODEC_ANY = 0xFFFFFFFE, + /* this one MUST be the last */ + TC_CODEC_ERROR = 0xFFFFFFFF +} TCCodecID; + +#endif // TC_CODECS_H diff --git a/debian/transcode/transcode-1.1.7/libtc/tcformats.h b/debian/transcode/transcode-1.1.7/libtc/tcformats.h new file mode 100644 index 00000000..d8f57853 --- /dev/null +++ b/debian/transcode/transcode-1.1.7/libtc/tcformats.h @@ -0,0 +1,81 @@ +/* + * tcformats.h + * + * Copyright (C) Thomas Oestreich - June 2001 + * ripped from 'magic.h' by Francesco Romani - November 2006 + * + * This file is part of transcode, a video stream processing tool + * + * transcode 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, or (at your option) + * any later version. + * + * transcode is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Make; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#ifndef TC_FORMATS_H +#define TC_FORMATS_H + +/* + * formats identifiers. + */ + +typedef enum { + /* audio only */ + TC_FORMAT_WAV, + TC_FORMAT_CDXA, + + /* video only */ + TC_FORMAT_YUV4MPEG, + TC_FORMAT_PVN, + + /* audio + video */ + TC_FORMAT_AVI, + TC_FORMAT_ASF, + TC_FORMAT_MOV, + TC_FORMAT_OGG, + TC_FORMAT_MPEG, /* generic, should not be used directly */ + TC_FORMAT_MPEG_ES, + TC_FORMAT_MPEG_PS, + TC_FORMAT_MPEG_TS, + TC_FORMAT_MPEG_PES, + TC_FORMAT_MPEG_VOB, + TC_FORMAT_MPEG_VDR, + TC_FORMAT_MPEG_MP4, + TC_FORMAT_MXF, + TC_FORMAT_PV3, + TC_FORMAT_VAG, + TC_FORMAT_NUV, + TC_FORMAT_FLV, + + /* special */ + TC_FORMAT_RAW, /* no container */ + TC_FORMAT_ALSA, + TC_FORMAT_X11, + TC_FORMAT_XML, + TC_FORMAT_VIDEO4LINUX, + TC_FORMAT_OSS, + TC_FORMAT_BKTR, + TC_FORMAT_VNC, + TC_FORMAT_DVD, + TC_FORMAT_DVD_PAL, /* temporary */ + TC_FORMAT_DVD_NTSC, /* temporary */ + + /* special (pseudo)formats */ + TC_FORMAT_UNKNOWN = 0x00000000, + TC_FORMAT_NULL = 0xFFFFFF00, /* drop content */ + TC_FORMAT_ANY = 0xFFFFFFFE, + /* this one MUST be the last */ + TC_FORMAT_ERROR = 0xFFFFFFFF +} TCFormatID; + +#endif // TC_FORMATS_H diff --git a/debian/transcode/transcode-1.1.7/libtc/tcframes.c b/debian/transcode/transcode-1.1.7/libtc/tcframes.c new file mode 100644 index 00000000..ff9fe6ac --- /dev/null +++ b/debian/transcode/transcode-1.1.7/libtc/tcframes.c @@ -0,0 +1,275 @@ +/* + * tcframes.c -- common generic audio/video/whatever frame allocation/disposal + * routines for transcode. + * (C) 2005-2010 - Francesco Romani <fromani -at- gmail -dot- com> + * + * This file is part of transcode, a video stream processing tool. + * + * transcode 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. + * + * transcode is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include "src/tc_defaults.h" + +#include "tcframes.h" + +int tc_video_planes_size(size_t psizes[3], + int width, int height, int format) +{ + switch (format) { + case CODEC_RAW: /* worst case paranoia, fallback */ + case CODEC_RAW_RGB: /* worst case paranoia again, fallback */ + case CODEC_RAW_YUV: /* worst case paranoia again, fallback */ + case CODEC_RGB: /* backward compatibility, fallback */ + case TC_CODEC_RGB: + psizes[0] = width * height; + psizes[1] = width * height; + psizes[2] = width * height; + break; + case CODEC_YUV422: /* backward compatibility, fallback */ + case TC_CODEC_YUV422P: + psizes[0] = width * height; + psizes[1] = width * height / 2; + psizes[2] = width * height / 2; + break; + case CODEC_YUV: /* backward compatibility, fallback */ + case TC_CODEC_YUV420P: + psizes[0] = width * height; + psizes[1] = width * height / 4; + psizes[2] = width * height / 4; + break; + default: /* unknown */ + psizes[0] = 0; + psizes[1] = 0; + psizes[2] = 0; + return TC_NULL_MATCH; + } + return 0; +} + +/* blank )set to zero) rightmost X bits of I */ +#define TRUNC_VALUE(i, x) (((i) >> (x)) << (x)) + +size_t tc_audio_frame_size(double samples, int channels, + int bits, int *adjust) +{ + double rawsize = samples * (bits/8) * channels; + size_t asize = TRUNC_VALUE(((size_t)rawsize), 2); + int leap1 = 0, leap2 = 0, leap = 0; + + leap1 = TC_LEAP_FRAME * (rawsize - asize); + leap2 = -leap1 + TC_LEAP_FRAME * (bits/8) * channels; + leap1 = TRUNC_VALUE(leap1, 2); + leap2 = TRUNC_VALUE(leap2, 2); + + if (leap1 < leap2) { + leap = leap1; + } else { + leap = -leap2; + asize += (bits/8) * channels; + } + *adjust = leap; + return asize; +} + +#undef TRUNC_VALUE + +void tc_init_video_frame(vframe_list_t *vptr, + int width, int height, int format) +{ + size_t psizes[3]; + + tc_video_planes_size(psizes, width, height, format); + + vptr->video_buf_RGB[0] = vptr->internal_video_buf_0; + vptr->video_buf_RGB[1] = vptr->internal_video_buf_1; + + vptr->video_buf_Y[0] = vptr->internal_video_buf_0; + vptr->video_buf_U[0] = vptr->video_buf_Y[0] + psizes[0]; + vptr->video_buf_V[0] = vptr->video_buf_U[0] + psizes[1]; + + vptr->video_buf_Y[1] = vptr->internal_video_buf_1; + vptr->video_buf_U[1] = vptr->video_buf_Y[1] + psizes[0]; + vptr->video_buf_V[1] = vptr->video_buf_U[1] + psizes[1]; + + vptr->video_buf = vptr->internal_video_buf_0; + vptr->video_buf2 = vptr->internal_video_buf_1; + vptr->free = 1; + + vptr->video_size = psizes[0] + psizes[1] + psizes[2]; + vptr->video_len = vptr->video_size; /* default */ +} + +void tc_init_audio_frame(aframe_list_t *aptr, + double samples, int channels, int bits) +{ + int unused = 0; + + aptr->audio_size = tc_audio_frame_size(samples, channels, bits, + &unused); + aptr->audio_buf = aptr->internal_audio_buf; +} + + +vframe_list_t *tc_new_video_frame(int width, int height, int format, + int partial) +{ + vframe_list_t *vptr = NULL; + size_t psizes[3] = { 0, 0, 0 }; + + int ret = tc_video_planes_size(psizes, width, height, format); + if (ret == 0) { + vptr = tc_alloc_video_frame(psizes[0] + psizes[1] + psizes[2], + partial); + + if (vptr != NULL) { + tc_init_video_frame(vptr, width, height, format); + } + } + return vptr; +} + +aframe_list_t *tc_new_audio_frame(double samples, int channels, int bits) +{ + aframe_list_t *aptr = NULL; + int unused = 0; + size_t asize = tc_audio_frame_size(samples, channels, bits, &unused); + + aptr = tc_alloc_audio_frame(asize); + + if (aptr != NULL) { + tc_init_audio_frame(aptr, samples, channels, bits); + } + return aptr; +} + +#define TC_FRAME_EXTRA_SIZE 128 + +/* + * About TC_FRAME_EXTRA_SIZE: + * + * This is an emergency parachute for codecs that delivers + * encoded frames *larger* than raw ones. Such beasts exists, + * even LZO does it in some (AFAIK uncommon) circumstances. + * + * On those cases, the Sane Thing To Do from the encoder + * viewpoint is to deliver an header + payload content, where + * 'header' is a standard frame header with one flag set + * (1 bit in the best, very unlikely, case) meaning that + * following payload is uncompressed. + * + * So, EXTRA_SIZE is supposed to catch such (corner) cases + * by providing enough extra data for sane headers (for example, + * LZO header is 16 byte long). + * + * Please note that this issue affects only + * demultiplexor -> decoder and + * encoder -> multiplexor communications. + * + * Yes, that's a bit hackish. Anyone has a better, more generic + * and clean solution? Remember that frames must be pre-allocated, + * allocating them on-demand isn't a viable alternative. + */ + +vframe_list_t *tc_alloc_video_frame(size_t size, int partial) +{ + vframe_list_t *vptr = tc_zalloc(sizeof(vframe_list_t)); + +#ifdef TC_FRAME_EXTRA_SIZE + size += TC_FRAME_EXTRA_SIZE; +#endif + + if (vptr != NULL) { +#ifdef STATBUFFER + vptr->internal_video_buf_0 = tc_bufalloc(size); + if (vptr->internal_video_buf_0 == NULL) { + tc_free(vptr); + return NULL; + } + if (!partial) { + vptr->internal_video_buf_1 = tc_bufalloc(size); + if (vptr->internal_video_buf_1 == NULL) { + tc_buffree(vptr->internal_video_buf_0); + tc_free(vptr); + return NULL; + } + } else { + vptr->internal_video_buf_1 = NULL; + } + vptr->video_size = size; +#endif /* STATBUFFER */ + } + return vptr; + +} + +aframe_list_t *tc_alloc_audio_frame(size_t size) +{ + aframe_list_t *aptr = tc_zalloc(sizeof(aframe_list_t)); + +#ifdef TC_FRAME_EXTRA_SIZE + size += TC_FRAME_EXTRA_SIZE; +#endif + + if (aptr != NULL) { +#ifdef STATBUFFER + aptr->internal_audio_buf = tc_bufalloc(size); + if (aptr->internal_audio_buf == NULL) { + tc_free(aptr); + return NULL; + } + aptr->audio_size = size; +#endif /* STATBUFFER */ + } + return aptr; +} + +void tc_del_video_frame(vframe_list_t *vptr) +{ + if (vptr != NULL) { +#ifdef STATBUFFER + if (vptr->internal_video_buf_1 != NULL) { + tc_buffree(vptr->internal_video_buf_1); + } + tc_buffree(vptr->internal_video_buf_0); +#endif + tc_free(vptr); + } +} + +void tc_del_audio_frame(aframe_list_t *aptr) +{ + if (aptr != NULL) { +#ifdef STATBUFFER + tc_buffree(aptr->internal_audio_buf); +#endif + tc_free(aptr); + } +} + +/*************************************************************************/ + +/* + * Local variables: + * c-file-style: "stroustrup" + * c-file-offsets: ((case-label . *) (statement-case-intro . *)) + * indent-tabs-mode: nil + * End: + * + * vim: expandtab shiftwidth=4: + */ diff --git a/debian/transcode/transcode-1.1.7/libtc/tcframes.h b/debian/transcode/transcode-1.1.7/libtc/tcframes.h new file mode 100644 index 00000000..0d8f4dfa --- /dev/null +++ b/debian/transcode/transcode-1.1.7/libtc/tcframes.h @@ -0,0 +1,491 @@ +/* + * tcframes.h -- common generic audio/video/whatever frame allocation/disposal + * routines for transcode. + * (C) 2005-2010 - Francesco Romani <fromani -at- gmail -dot- com> + * + * This file is part of transcode, a video stream processing tool. + * + * transcode 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. + * + * transcode is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + + +#ifndef TCFRAMES_H +#define TCFRAMES_H + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include <stdarg.h> +#include <stdint.h> +#include <sys/types.h> + +#include "libtc/libtc.h" +#include "libtc/tctimer.h" +#include "libtc/tccodecs.h" + + +/*************************************************************************/ + +/* frame attributes */ +typedef enum tcframeattributes_ TCFrameAttributes; +enum tcframeattributes_ { + TC_FRAME_IS_KEYFRAME = 1, + TC_FRAME_IS_INTERLACED = 2, + TC_FRAME_IS_BROKEN = 4, + TC_FRAME_IS_SKIPPED = 8, + TC_FRAME_IS_CLONED = 16, + TC_FRAME_WAS_CLONED = 32, + TC_FRAME_IS_OUT_OF_RANGE = 64, + TC_FRAME_IS_DELAYED = 128, + TC_FRAME_IS_END_OF_STREAM = 256, +}; + +#define TC_FRAME_NEED_PROCESSING(PTR) \ + (!((PTR)->attributes & TC_FRAME_IS_OUT_OF_RANGE) \ + && !((PTR)->attributes & TC_FRAME_IS_END_OF_STREAM)) + +typedef enum tcframestatus_ TCFrameStatus; +enum tcframestatus_ { + TC_FRAME_NULL = -1, /* on the frame pool, not yet claimed */ + TC_FRAME_EMPTY = 0, /* claimed and being filled by decoder */ + TC_FRAME_WAIT, /* needs further processing (filtering) */ + TC_FRAME_LOCKED, /* being procedded by filter layer */ + TC_FRAME_READY, /* ready to be processed by encoder */ +}; + +/* + * frame status transitions scheme (overview) + * + * + * .-------<----- +-------<------+------<------+-------<-------. + * | ^ ^ ^ ^ + * V | | | | + * FRAME_NULL -> FRAME_EMPTY -> FRAME_WAIT -> FRAME_LOCKED -> FRAME_READY + * :_buffer_: \_decoder_/ \______filter_stage______/ \encoder_%/ + * \__pool__/ | : ^ : + * | \_______________encoder $__________|____/ + * V ^ + * `-------------->------------->---------------' + * + * Notes: + * % - regular case, frame (processing) threads avalaibles + * $ - practical (default) case, filtering is carried by encoder thread. + */ + +/*************************************************************************/ + +/* + * NOTE: The following warning will become irrelevant once NMS is + * in place, and frame_list_t can go away completely. --AC + * (here's a FIXME tag so we don't forget) + * + * BIG FAT WARNING: + * + * These structures must be kept in sync: meaning that if you add + * another field to the vframe_list_t you must add it at the end + * of the structure. + * + * aframe_list_t, vframe_list_t and the wrapper frame_list_t share + * the same offsets to their elements up to the field "size". That + * means that when a filter is called with at init time with the + * anonymouse frame_list_t, it can already access the size. + * + * -- tibit + */ + +/* This macro factorizes common frame data fields. + * Is not possible to completely factor out all frame_list_t fields + * because video and audio typess uses different names for same fields, + * and existing code relies on this assumption. + * Fixing this is stuff for 1.2.0 and beyond, for which I would like + * to introduce some generic frame structure or something like it. -- FR. + */ +#define TC_FRAME_COMMON \ + int id; /* frame id (sequential uint) */ \ + int bufid; /* buffer id */ \ + int tag; /* init, open, close, ... */ \ + int filter_id; /* filter instance to run */ \ + TCFrameStatus status; /* see enumeration above */ \ + TCFrameAttributes attributes; /* see enumeration above */ \ + TCTimestamp timestamp; \ +/* BEWARE: semicolon NOT NEEDED */ + +/* + * Size vs Length + * + * Size represent the effective size of audio/video buffer, + * while length represent the amount of valid data into buffer. + * Until 1.1.0, there isn't such distinction, and 'size' + * have approximatively a mixed meaning of above. + * + * In the long shot[1] (post-1.1.0) transcode will start + * intelligently allocate frame buffers based on highest + * request of all modules (core included) through filter + * mangling pipeline. This will lead on circumstances on + * which valid data into a buffer is less than buffer size: + * think to demuxer->decoder transition or RGB24->YUV420. + * + * There also are more specific cases like a full-YUV420P + * pipeline with final conversion to RGB24 and raw output, + * so we can have something like + * + * framebuffer size = sizeof(RGB24_frame) + * after demuxer: + * frame length << frame size (compressed data) + * after decoder: + * frame length < frame size (YUV420P smaller than RGB24) + * in filtering: + * frame length < frame size (as above) + * after encoding (in fact just colorspace transition): + * frame length == frame size (data becomes RGB24) + * into muxer: + * frame length == frame size (as above) + * + * In all those cases having a distinct 'lenght' fields help + * make things nicer and easier. + * + * +++ + * + * [1] in 1.1.0 that not happens due to module interface constraints + * since we're still bound to Old Module System. + */ + +#define TC_FRAME_GET_TIMESTAMP_UINT(FP) ((FP)->timestamp.u) +#define TC_FRAME_GET_TIMESTAMP_DOUBLE(FP) ((FP)->timestamp.d) +#define TC_FRAME_SET_TIMESTAMP_UINT(FP, TS) ((FP)->timestamp.u = (uint64_t)(TS)) +#define TC_FRAME_SET_TIMESTAMP_DOUBLE(FP, TS) ((FP)->timestamp.d = (double)(TS)) + +typedef struct tcframe_ TCFrame; +struct tcframe_ { + TC_FRAME_COMMON + + int codec; /* codec identifier */ + + int size; /* buffer size avalaible */ + int len; /* how much data is valid? */ + + int param1; /* v_width or a_rate */ + int param2; /* v_height or a_bits */ + int param3; /* v_bpp or a_chan */ + + struct tcframe_ *next; + struct tcframe_ *prev; +}; +typedef struct tcframe_ frame_list_t; + + +typedef struct tcframevideo_ TCFrameVideo; +struct tcframevideo_ { + TC_FRAME_COMMON + /* frame physical parameter */ + + int v_codec; /* codec identifier */ + + int video_size; /* buffer size avalaible */ + int video_len; /* how much data is valid? */ + + int v_width; + int v_height; + int v_bpp; + + struct tcframevideo_ *next; + struct tcframevideo_ *prev; + + uint8_t *video_buf; /* pointer to current buffer */ + uint8_t *video_buf2; /* pointer to backup buffer */ + + int free; /* flag */ + +#ifdef STATBUFFER + uint8_t *internal_video_buf_0; + uint8_t *internal_video_buf_1; +#else + uint8_t internal_video_buf_0[SIZE_RGB_FRAME]; + uint8_t internal_video_buf_1[SIZE_RGB_FRAME]; +#endif + + int deinter_flag; + /* set to N for internal de-interlacing with "-I N" */ + + uint8_t *video_buf_RGB[2]; + + uint8_t *video_buf_Y[2]; + uint8_t *video_buf_U[2]; + uint8_t *video_buf_V[2]; +}; +typedef struct tcframevideo_ vframe_list_t; + + +typedef struct tcframeaudio_ TCFrameAudio; +struct tcframeaudio_ { + TC_FRAME_COMMON + + int a_codec; /* codec identifier */ + + int audio_size; /* buffer size avalaible */ + int audio_len; /* how much data is valid? */ + + int a_rate; + int a_bits; + int a_chan; + + struct tcframeaudio_ *next; + struct tcframeaudio_ *prev; + + uint8_t *audio_buf; + uint8_t *audio_buf2; + + int free; /* flag */ + +#ifdef STATBUFFER + uint8_t *internal_audio_buf; + uint8_t *internal_audio_buf_1; +#else + uint8_t internal_audio_buf[SIZE_PCM_FRAME * 2]; + uint8_t internal_audio_buf_1[SIZE_PCM_FRAME * 2]; +#endif +}; +typedef struct tcframeaudio_ aframe_list_t; + +/* + * generic pointer type, needed at least by internal code. + * In the long (long) shot I'd like to use a unique generic + * data container, like AVPacket (libavcodec) or something like it. + * (see note about TC_FRAME_COMMON above) -- FR + */ +typedef union tcframeptr_ TCFramePtr; +union tcframeptr_ { + TCFrame *generic; + TCFrameVideo *video; + TCFrameAudio *audio; +}; + +/*************************************************************************/ + + +/* + * tc_video_planes_size: + * compute the size of video planes given frame size and frame format. + * Recognizes only video formats used in transcode. + * + * Parameters: + * psizes: array of size that will be filled with size of respective + * plane, in order. If given format isn't a planar one, only + * first element in array is significant. + * width: width of video frame + * height: height of video frame + * format: format of video frame + * Return Value: + * >= 0 if succesfull, + * TC_NULL_MATCH otherwise (wrong/unknown parameters) + */ +int tc_video_planes_size(size_t psizes[3], + int width, int height, int format); + +/* + * tc_video_frame_size: + * little helper function that returns the full dimension of a + * video frame given dimensions and format. + * + * Parameters: + * width: width of video frame + * height: height of video frame + * format: format of video frame + * Return Value: + * size in bytes of video frame + */ +#ifdef HAVE_GCC_ATTRIBUTES +__attribute__((unused)) +#endif +static size_t tc_video_frame_size(int width, int height, int format) +{ + size_t psizes[3] = { 0, 0, 0 }; + tc_video_planes_size(psizes, width, height, format); + return (psizes[0] + psizes[1] + psizes[2]); +} + +/* + * OK, we have sample rate. But sample rate means "[audio] samples PER SECOND" + * and we want audio samples PER FRAME. + */ +#define TC_AUDIO_SAMPLES_IN_FRAME(rate, fps) ((double)rate/(double)fps) + +/* + * tc_audio_frame_size: + * compute the size of buffer needed to store the audio data described by + * given specifiers. + * + * Parameters: + * samples: audio samples PER FRAME. Can (and it's likely that it will) + * be a real numner (values after the point are significant!) + * channels: audio channels. + * bits: audio BITS for sample. + * adjust: store here adjustement value. Such value means how much extra + * buffer size it's needed to safely store extra samples. + * We have extra samples when rate/fps != 0, so we can + * spread all samples in frames, there is something that + * "exceed" :) + * (OK, there is *A LOT* of room for improvement here. But this + * API it's also driven by legacy code). + * Return Value: + * amount of buffer needed. + * Preconditions: + * adjust != NULL. + */ +size_t tc_audio_frame_size(double samples, int channels, + int bits, int *adjust); + +/* + * tc_alloc_{video,audio}_frame: + * allocate, but NOT initialize, a {TCFrameVideo,TCFrameAudio}, + * large enough to hold a video frame large as given size. + * This function guarantee that video buffer(s) memory will + * be page-aligned. + * + * Parameters: + * size: size in bytes of video frame that will be contained. + * partial: if !0, doesn't allocate secondary video buffer, + * but only primary. This allow to save memory since + * secondary video buffer isn't ALWAYS needed. + * Return Value: + * pointer to a new TCFrameVideo (free it using tc_del_video_frame, + * not manually! ) if succesfull, NULL otherwise. + */ +TCFrameVideo *tc_alloc_video_frame(size_t size, int partial); +TCFrameAudio *tc_alloc_audio_frame(size_t size); + + +/* + * tc_init_video_frame: + * properly (re)initialize an already-allocated video frame, by + * asjusting plane pointers, (re)setting video buffer pointers, + * cleaning flags et. al. + * You usually always need to use this function unless you + * perfectly knows what you're doing. + * Do nothing if missing TCFrameVideo to (re)initialize of + * one or more parameter are wrong. + * + * Parameters: + * vptr: pointer to TCFrameVideo to (re)initialize. + * width: video frame width. + * height: video frame height. + * format: video frame format. + * Return Value: + * None + * Preconditions: + * given TCFrameVideo MUST be already allocated to be large + * enough to safely store a video frame with given + * parameters. This function DO NOT check if this precondition + * is respected. + */ +void tc_init_video_frame(TCFrameVideo *vptr, + int width, int height, int format); +/* + * tc_init_audio_frame: + * properly (re)initialize an already-allocated audio frame, + * (re)setting video buffer pointers,cleaning flags et. al. + * You usually always need to use this function unless you + * perfectly knows what you're doing. + * Do nothing if missing TCFrameAudio to (re)initialize of + * one or more parameter are wrong. + * + * Parameters: + * aptr: pointer to TCFrameAudio to (re)initialize. + * samples: audio frame samples that this audio frame + * will contain (WARNING: TCFrameAudio MUST + * be allocated accordingly). + * channels: audio frame channels. + * bits: audio frame bit for sample. + * Return Value: + * None + * Preconditions: + * given TCFrameAudio MUST be already allocated to be large + * enough to safely store an audio frame with given + * parameters. This function DO NOT check if this precondition + * is respected. + */ +void tc_init_audio_frame(TCFrameAudio *aptr, + double samples, int channels, int bits); + +/* + * tc_new_video_frame: + * allocate and initialize a new TCFrameVideo large enough + * to hold a video frame represented by given parameters. + * This function guarantee that video buffer(s) memory will + * be page-aligned. + * + * Parameters: + * width: video frame width. + * height: video frame height. + * format: video frame format. + * partial: if !0, doesn't allocate secondary video buffer, + * but only primary. This allow to save memory since + * secondary video buffer isn't ALWAYS needed. + * Return Value: + * pointer to a new TCFrameVideo (free it using tc_del_video_frame, + * not manually! ) if succesfull, NULL otherwise. + */ +TCFrameVideo *tc_new_video_frame(int width, int height, int format, + int partial); + +/* + * tc_new_audio_frame: + * allocate and initialize a new TCFrameAudio large enough + * to hold an audio frame represented by given parameters. + * This function guarantee that audio buffer memory will + * be page-aligned. + * + * Parameters: + * samples: audio frame samples that this audio frame + * will contain (WARNING: TCFrameAudio MUST + * be allocated accordingly). + * channels: audio frame channels. + * bits: audio frame bit for sample. + * Return Value: + * pointer to a new TCFrameAudio (free it using tc_del_audio_frame, + * not manually! ) if succesfull, NULL otherwise. + */ +TCFrameAudio *tc_new_audio_frame(double samples, int channels, int bits); + + +/* + * tc_del_{video,audio}_frame: + * safely deallocate memory obtained with tc_new_{video,audio}_frame + * or tc_alloc_{video,audio}_frame. + * + * Parameters: + * {vptr,aptr}: a pointer to a TCFrame{Video,Audio} obtained by calling + * tc_new_{video,audio}_frame or tc_alloc_{video,audio}_frame. + * Return Value: + * None + */ +void tc_del_video_frame(TCFrameVideo *vptr); +void tc_del_audio_frame(TCFrameAudio *aptr); + +/* + * tc_blank_{video,audio}_frame: + * fill a provided frame with per-format valid but blank (null) + * content. + * + * Parameters: + * ptr: pointer to frame to fill. + * Return Value: + * None. + */ +void tc_blank_video_frame(TCFrameVideo *ptr); +void tc_blank_audio_frame(TCFrameAudio *ptr); + + +#endif /* TCFRAMES_H */ diff --git a/debian/transcode/transcode-1.1.7/libtc/tcglob.c b/debian/transcode/transcode-1.1.7/libtc/tcglob.c new file mode 100644 index 00000000..17fdb864 --- /dev/null +++ b/debian/transcode/transcode-1.1.7/libtc/tcglob.c @@ -0,0 +1,121 @@ +/* + * tcglob.c -- simple iterator over a path collection expressed through + * glob (7) semantic (implementation). + * (C) 2007-2010 - Francesco Romani <fromani -at- gmail -dot- com> + * + * This file is part of transcode, a video stream processing tool. + * + * transcode 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. + * + * transcode is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + + +#include <string.h> +#include <glob.h> + +#include "libtc.h" +#include "tcglob.h" + + +struct tcglob_ { + const char *pattern; + glob_t glob; + int current; +}; + +#define GLOB_NOERROR 0 + + +TCGlob *tc_glob_open(const char *pattern, uint32_t flags) +{ + TCGlob *tcg = NULL; + flags = GLOB_ERR; /* flags intentionally overridden */ + + if (pattern != NULL && strlen(pattern) > 0) { + tcg = tc_malloc(sizeof(TCGlob)); + + if (tcg != NULL) { + int err = 0; + + tcg->pattern = NULL; + + err = glob(pattern, flags, NULL, &(tcg->glob)); + + switch (err) { + case GLOB_NOMATCH: + tcg->pattern = tc_strdup(pattern); // XXX + tcg->current = -1; + break; + case GLOB_NOERROR: + tcg->current = 0; + break; + default: /* any other error: clean it up */ + tc_log_error(__FILE__, "internal glob failed (code=%i)", + err); + tc_free(tcg); + tcg = NULL; + } + } + } + return tcg; +} + + +const char *tc_glob_next(TCGlob *tcg) +{ + const char *ret = NULL; + if (tcg != NULL) { + if (tcg->current == -1) { + ret = tcg->pattern; + } + if (tcg->current < tcg->glob.gl_pathc) { + ret = tcg->glob.gl_pathv[tcg->current]; + } + tcg->current++; + } + return ret; +} + +int tc_glob_has_more(TCGlob *tcg) +{ + if (tcg == NULL) { + return 0; + } + return (tcg->current < tcg->glob.gl_pathc) + (tcg->pattern != NULL); +} + + +int tc_glob_close(TCGlob *tcg) +{ + if (tcg != NULL) { + if (tcg->pattern != NULL) { + tc_free((void*)tcg->pattern); + tcg->pattern = NULL; + } + globfree(&(tcg->glob)); + tc_free(tcg); + } + return TC_OK; +} + +/*************************************************************************/ + +/* + * Local variables: + * c-file-style: "stroustrup" + * c-file-offsets: ((case-label . *) (statement-case-intro . *)) + * indent-tabs-mode: nil + * End: + * + * vim: expandtab shiftwidth=4: + */ diff --git a/debian/transcode/transcode-1.1.7/libtc/tcglob.h b/debian/transcode/transcode-1.1.7/libtc/tcglob.h new file mode 100644 index 00000000..faf4cf04 --- /dev/null +++ b/debian/transcode/transcode-1.1.7/libtc/tcglob.h @@ -0,0 +1,107 @@ +/* + * tcglob.h -- simple iterator over a path collection expressed through + * glob (7) semantic. + * (C) 2007-2010 - Francesco Romani <fromani -at- gmail -dot- com> + * + * This file is part of transcode, a video stream processing tool. + * + * transcode 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. + * + * transcode is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + + +#ifndef TCGLOB_H +#define TCGLOB_H + +/* + * Quick Summary: + * this code iterates over a collection of pathnames expressed through + * glob (7) syntax, in a compact, consolidated and efficient way. + * The intended usage of this code is as iterator/pathname generator. + * + */ + +#include <stdint.h> + +/* opaque type */ +typedef struct tcglob_ TCGlob; + + +/* + * tc_glob_open: + * create a new TCGlob structure based on a given pathname + * glob expression. + * + * Parameters: + * pattern: glob pattern expression to be expanded + * flags: currently unused (use 0 (zero)). + * Return Value: + * if succesfull, a newly-allocated TCGlob structure ready + * to be used through tc_glob_* functions; + * (use tc_glob_close() to dispose it) + * NULL if failed. + */ +TCGlob *tc_glob_open(const char *pattern, uint32_t flags); + + +/* + * tc_glob_next: + * get new expanded pathname from given tcglob structure. + * + * Parameters: + * tcg: pointer to TCGlob structure to be used. + * Return Value: + * if succesfull, a constant pointer to the next expanded pathname. + * there is NO NEED to free() it explicitely after usage. + * The returned pointer is guaranteed to be valid AT LEAST until + * next tc_glob_next() call, but not after. + * if failed, returns NULL. + * PLEASE NOTE that this function returns NULL also if all pathnames + * are been expanded, so there is NO MORE pathname to get. + * You can safely think that returning NULL acts as 'guard condition' + * meaning something like 'iteration must end here'. + * (see also tc_glob_has_more) + */ +const char *tc_glob_next(TCGlob *tcg); + + +/* + * tc_glob_has_more: + * tell if current glob expression has at least one more pathname to + * be expanded (= is terminated) or not. + * + * Parameters: + * tcg: pointer to TCGlob structure to be checked. + * Return Value: + * > 0: pathname expansion not yet ended (= there is at least one more + * pathname to get with tc_glob_next) + * 0: pathname expansion ended. + */ +int tc_glob_has_more(TCGlob *tcg); + + +/* + * tc_glob_close: + * finalize a TCGlob structure and release all resources acquired via + * tc_glob_open. Subsequent tc_glob_* calls using this TCGlob structure + * will lead to undefined behaviour. + * + * Parameters: + * tcg: pointer to TCGlob structure to be finalized. + * Return Value: + * !0: succesfull. + * 0: otherwise. + */ +int tc_glob_close(TCGlob *tcg); + +#endif /* TCGLOB_H */ diff --git a/debian/transcode/transcode-1.1.7/libtc/tclist.c b/debian/transcode/transcode-1.1.7/libtc/tclist.c new file mode 100644 index 00000000..31c4a55b --- /dev/null +++ b/debian/transcode/transcode-1.1.7/libtc/tclist.c @@ -0,0 +1,387 @@ +/* + * tclist.c -- a list for transcode / implementation + * (C) 2008-2010 - Francesco Romani <fromani -at- gmail -dot- com> + * + * This file is part of transcode, a video stream processing tool. + * + * transcode 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. + * + * transcode is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + + +#include "libtc.h" +#include "tclist.h" + +/*************************************************************************/ + +enum { + DIR_BACKWARD = -1, + DIR_FORWARD = +1 +}; + +static int free_item(TCListItem *item, void *unused) +{ + tc_free(item); + return 0; +} + +static TCListItem* next_item(TCListItem *cur, int direction) +{ + TCListItem *ret = NULL; + if (cur) { + if (direction == DIR_BACKWARD) { + ret = cur->prev; + } else { + ret = cur->next; + } + } + return ret; +} + +static TCListItem *start_item(TCList *L, int direction) +{ + TCListItem *ret = NULL; + if (L) { + if (direction == DIR_BACKWARD) { + ret = L->tail; + } else { + ret = L->head; + } + } + return ret; +} + +static void del_item(TCList *L, TCListItem *IT) +{ + if (L->use_cache) { + IT->prev = NULL; + IT->data = NULL; + IT->next = L->cache; + L->cache = IT; + } else { + tc_free(IT); + } +} + +static TCListItem *new_item(TCList *L) +{ + TCListItem *IT = NULL; + if (L->use_cache && L->cache) { + IT = L->cache; + L->cache = L->cache->next; + } else { + IT = tc_zalloc(sizeof(TCListItem)); + } + return IT; +} + +static int foreach_item(TCListItem *start, int direction, + TCListVisitor vis, void *userdata) +{ + int ret = 0; + TCListItem *cur = NULL, *inc = NULL; + + for (cur = start; cur; cur = inc) { + inc = next_item(cur, direction); + ret = vis(cur, userdata); + if (ret != 0) { + break; + } + } + + return ret; +} + +struct find_data { + int dir; + int cur_idx; + int stop_idx; + TCListItem *ptr; +}; + +static int elem_finder(TCListItem *item, void *userdata) +{ + struct find_data *FD = userdata; + int ret = 0; + + FD->ptr = item; + + if (FD->cur_idx != FD->stop_idx) { + FD->cur_idx += FD->dir; + } else { + ret = 1; + } + return ret; +} + +static TCListItem *find_position(TCList *L, int pos) +{ + TCListItem *ret = NULL; + if (L) { + /* common cases first */ + if (pos == 0) { + ret = L->head; + } else if (pos == -1) { + ret = L->tail; + } else { + /* if we're here we can't avoid a full scan */ + struct find_data FD = { DIR_FORWARD, 0, 0, NULL }; + if (pos >= 0) { + FD.dir = DIR_FORWARD; /* enforce */ + FD.cur_idx = 0; + FD.stop_idx = pos; + } else { + /* + * we're perfectly fine with negative indexes; + * we'll just starting from the end going backwards + * with -1 being the last element. + */ + FD.dir = DIR_BACKWARD; + FD.cur_idx = L->nelems - 1; + FD.stop_idx = L->nelems + pos; + } + /* we can now catch some over/under-run common cases */ + if (FD.stop_idx > 0 || FD.stop_idx < L->nelems) { + /* we want something in the middle, so let's run */ + FD.ptr = NULL; /* for safeness */ + foreach_item(start_item(L, FD.dir), FD.dir, elem_finder, &FD); + ret = FD.ptr; /* cannot fail */ + } + } + } + return ret; +} + +static int item_insert_before(TCList *L, int pos, void *data) +{ + int ret = TC_ERROR; + TCListItem *ref = find_position(L, pos); + if (ref) { + TCListItem *ext = new_item(L); + if (ext) { + ext->data = data; + ref->prev->next = ext; + ext->prev = ref->prev; + ext->next = ref; + ref->prev = ext; + L->nelems++; + ret = TC_OK; + } + } + return ret; +} + +static int item_insert_after(TCList *L, int pos, void *data) +{ + int ret = TC_ERROR; + TCListItem *ref = find_position(L, pos); + if (ref) { + TCListItem *ext = new_item(L); + if (ext) { + ext->data = data; + ref->next->prev = ext; + ext->next = ref->next; + ext->prev = ref; + ref->next = ext; + L->nelems++; + ret = TC_OK; + } + } + return ret; +} + +/*************************************************************************/ + +int tc_list_init(TCList *L, int elemcache) +{ + if (L) { + L->head = NULL; + L->tail = NULL; + L->nelems = 0; + L->cache = NULL; + L->use_cache = elemcache; + + return 0; + } + return -1; +} + +int tc_list_fini(TCList *L) +{ + /* if !use_cache, this will not hurt anyone */ + foreach_item(L->head, DIR_FORWARD, free_item, NULL); + foreach_item(L->cache, DIR_FORWARD, free_item, NULL); + /* now reset to clean status */ + return tc_list_init(L, 0); +} + +int tc_list_size(TCList *L) +{ + return (L) ?L->nelems :0; +} + +int tc_list_foreach(TCList *L, TCListVisitor vis, void *userdata) +{ + return foreach_item(L->head, DIR_FORWARD, vis, userdata); +} + +int tc_list_append(TCList *L, void *data) +{ + int ret = TC_ERROR; + TCListItem *IT = new_item(L); + + if (IT) { + IT->data = data; + IT->prev = L->tail; + if (!L->head) { + L->head = IT; + } else { + /* at least one element */ + L->tail->next = IT; + } + L->tail = IT; + L->nelems++; + + ret = TC_OK; + } + return ret; +} + +int tc_list_prepend(TCList *L, void *data) +{ + int ret = TC_ERROR; + TCListItem *IT = new_item(L); + + if (IT) { + IT->data = data; + IT->next = L->head; + if (!L->tail) { + L->tail = IT; + } else { + /* at least one element */ + L->head->prev = IT; + } + L->head = IT; + L->nelems++; + + ret = TC_OK; + } + return ret; +} + + +int tc_list_insert(TCList *L, int pos, void *data) +{ + int ret = TC_ERROR; + if (L && data) { + if (pos == 0) { + ret = tc_list_prepend(L, data); + } else if (pos == -1) { + ret = tc_list_append(L, data); + } else if (pos > 0) { + ret = item_insert_before(L, pos, data); + } else { + ret = item_insert_after(L, pos, data); + } + } + return ret; +} + +void *tc_list_get(TCList *L, int pos) +{ + TCListItem *IT = find_position(L, pos); + return (IT) ?IT->data :NULL; +} + +void *tc_list_pop(TCList *L, int pos) +{ + TCListItem *IT = find_position(L, pos); + void *data = NULL; + if (IT) { + data = IT->data; + if (L->head == IT) { + if (IT->next) { + IT->next->prev = NULL; + } + L->head = IT->next; + } else if (L->tail == IT) { + if (IT->prev) { + IT->prev->next = NULL; + } + L->tail = IT->prev; + } else { + IT->next->prev = IT->prev; + IT->prev->next = IT->next; + } + + del_item(L, IT); + L->nelems--; + } + return data; +} + +/*************************************************************************/ + +int tc_list_insert_dup(TCList *L, int pos, void *data, size_t size) +{ + int ret = TC_ERROR; + void *mem = tc_malloc(size); + if (mem) { + memcpy(mem, data, size); + ret = tc_list_insert(L, pos, mem); + if (ret == TC_ERROR) { + tc_free(mem); + } + } + return ret; +} + +static int free_item_all(TCListItem *item, void *unused) +{ + if (item->data != NULL) { + free(item->data); + } + free(item); + return 0; +} + +void tc_list_del(TCList *L, int deepclean) +{ + if (deepclean) { + foreach_item(L->head, DIR_FORWARD, free_item_all, NULL); + /* if !use_cache, this will not hurt anyone */ + foreach_item(L->cache, DIR_FORWARD, free_item_all, NULL); + } + tc_free(L); +} + +TCList *tc_list_new(int usecache) +{ + TCList *L = tc_malloc(sizeof(TCList)); + if (L) { + tc_list_init(L, usecache); + } + return L; +} + +/*************************************************************************/ + +/* + * Local variables: + * c-file-style: "stroustrup" + * c-file-offsets: ((case-label . *) (statement-case-intro . *)) + * indent-tabs-mode: nil + * End: + * + * vim: expandtab shiftwidth=4: + */ diff --git a/debian/transcode/transcode-1.1.7/libtc/tclist.h b/debian/transcode/transcode-1.1.7/libtc/tclist.h new file mode 100644 index 00000000..a11dd36c --- /dev/null +++ b/debian/transcode/transcode-1.1.7/libtc/tclist.h @@ -0,0 +1,190 @@ +/* + * tclist.h -- a list for transcode / interface + * (C) 2008-2010 - Francesco Romani <fromani -at- gmail -dot- com> + * + * This file is part of transcode, a video stream processing tool. + * + * transcode 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. + * + * transcode is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef TCLIST_H +#define TCLIST_H + +typedef struct tclistitem_ TCListItem; +struct tclistitem_ { + void *data; + TCListItem *next; + TCListItem *prev; +}; + +typedef struct tclist_ TCList; +struct tclist_ { + TCListItem *head; + TCListItem *tail; + TCListItem *cache; + int use_cache; + int nelems; +}; + +/* + * LIST INDEXING NOTE: + * ----------------------------------------------------------------------- + * WRITEME + */ + +/* + * TCListVisitor: + * typedef for visitor function. + * A visitor function is called on elements of a given list (usually + * on each element) giving to it pointers to current element and custom + * user data. It is safe to modify the element data inside the visitor + * function, even free()ing it. But DO NOT modify the list *item* + * inside this function. Use the special crafted upper-level list + * functions for that. + * + * Parameters: + * item: pointer to the list item currently visited. + * userdata: pointer to custom, opaque caller-given data. + * Return Value: + * 0: success. Iteration continues to the next element, if any. + * !0: failure. Iteration stops here. + */ +typedef int (*TCListVisitor)(TCListItem *item, void *userdata); + +/* + * tc_list_init: + * intializes a list data structure. + * A list can use a deleted element cache. The deleted list elements + * (NOT the data pointed by them!) are not really released until the + * tc_list_fini() is called, but they are just saved (in the `cache' + * field. + * Use the cache feature if ALL the following conditions are met: + * - you will do a lot of insertion/removals. + * - you will stabilize the list size around a given size. + * Otherwise using the cache will not hurt, but it will neither help. + * + * Parameters: + * L: pointer to list to be initialized. + * elemcache: treated as boolean, enables or disable the internal cache. + * Return Value: + * TC_OK on success, + * TC_ERROR on error. + */ +int tc_list_init(TCList *L, int elemcache); + +/* + * tc_list_fini: + * finalizes a list data structure. Frees all resources aquired, + * including any cached list element (if any), but *NOT* the data + * pointed by list elements. + * + * Parameters: + * L: pointer to list to be finalized + * Return Value: + * TC_OK on success, + * TC_ERROR on error. + */ +int tc_list_fini(TCList *L); + +/* + * tc_list_size: + * gives the number of elements present in the list. + * + * Parameters: + * L: list to be used. + * Return Value: + * -1 on error, + * the number of elements otherwise + */ +int tc_list_size(TCList *L); + +/* + * tc_list_foreach: + * applies a visitor function to all elements in the given lists, + * halting at first visit failed. + * + * Parameters: + * L: pointer to list to be visited. + * vis: visitor function to be applied. + * userdata: pointer to opaque data to be passed unchanged to visitor + * function at each call. + * Return Value: + * 0: if all elements are visited correctly. + * !0: the value returned by the first failed call to visitor function. + */ +int tc_list_foreach(TCList *L, TCListVisitor vis, void *userdata); + +/* + * tc_list_{append,prepend}: + * append or prepend an element to the list. + * The element is added on the {last,first} position of the list. + * + * Parameters: + * L: pointer to list to be used + * data: pointer to data to be appended or prepend. + * *PLEASE NOTE* that JUST THE POINTER is copied on the newly-added + * element. NO deep copy is performed. + * The caller has to allocate memory by itself if it want to + * add a copy of the data. + * Return Value: + * TC_OK on success, + * TC_ERROR on error. + */ +int tc_list_append(TCList *L, void *data); +int tc_list_prepend(TCList *L, void *data); + +/* + * tc_list_insert: + * the newly-inserted elements BECOMES the position `pos' on the list. + * Position after the last -> the last. + * Position before the first -> the first. + */ +int tc_list_insert(TCList *L, int pos, void *data); + +/* + * tc_list_get: + * gives access to the data pointed by the element in the given position. + * + * Parameters: + * L: list to be accessed. + * pos: position of the element on which the data will be returned. + * Return Value: + * NULL on error (requested element doesn't exist) + * a pointer to the data belonging to the requested list item. + */ +void *tc_list_get(TCList *L, int pos); + +/* + * tc_list_pop: + * removes the element in the given position. + * + * Parameters: + * L: list to be accessed. + * pos: position of the element on which the data will be returned. + * Return Value: + * NULL on error (requested element doesn't exist) + * a pointer to the data assigned to the requested list item. + */ +void *tc_list_pop(TCList *L, int pos); + +/*************************************************************************/ + +TCList *tc_list_new(int usecache); +void tc_list_del(TCList *L, int deepclean); + +int tc_list_insert_dup(TCList *L, int pos, void *data, size_t size); +#define tc_list_append_dup(L, DATA, SIZE) tc_list_insert_dup(L, -1, DATA, SIZE) +#define tc_list_prepend_dup(L, DATA, SIZE) tc_list_insert_dup(L, 0, DATA, SIZE) + +#endif /* TCLIST_H */ diff --git a/debian/transcode/transcode-1.1.7/libtc/tcmodule-core.h b/debian/transcode/transcode-1.1.7/libtc/tcmodule-core.h new file mode 100644 index 00000000..50a8f338 --- /dev/null +++ b/debian/transcode/transcode-1.1.7/libtc/tcmodule-core.h @@ -0,0 +1,442 @@ +/* + * tcmodule-core.h -- transcode module system, take two: core components. + * (C) 2005-2010 - Francesco Romani <fromani -at- gmail -dot- com> + * + * This file is part of transcode, a video stream processing tool. + * + * transcode 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. + * + * transcode is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + + + +/* + * this header file is intended to be included in components + * which want to use the new transcode module system, acting like + * clients respect to a plugin. + */ + +#ifndef TCMODULE_CORE_H +#define TCMODULE_CORE_H + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include <stdint.h> + +#include "tcmodule-data.h" /* pulls framebuffer.h and transcode.h */ + +/* + * this structure will hold all data needed to use a module by client code: + * module operations and capabilities (given by module class, so shared + * between all modules) and private data. + */ +typedef struct tcmodule_ *TCModule; +struct tcmodule_ { + const TCModuleClass *klass; + /* pointer to class data shared between all instances */ + + TCModuleInstance instance; + /* each module has it's private instance data, it's embedded here */ +}; + +/************************************************************************* + * interface helpers, using shortened notation * + *************************************************************************/ + +#ifdef HAVE_GCC_ATTRIBUTES +__attribute__((unused)) +#endif +static int tc_module_configure(TCModule handle, + const char *options, vob_t *vob) +{ + return handle->klass->configure(&(handle->instance), options, vob); +} + +#ifdef HAVE_GCC_ATTRIBUTES +__attribute__((unused)) +#endif +static int tc_module_stop(TCModule handle) +{ + return handle->klass->stop(&(handle->instance)); +} + +#ifdef HAVE_GCC_ATTRIBUTES +__attribute__((unused)) +#endif +static int tc_module_inspect(TCModule handle, + const char *param, const char **value) +{ + return handle->klass->inspect(&(handle->instance), param, value); +} + +#ifdef HAVE_GCC_ATTRIBUTES +__attribute__((unused)) +#endif +static int tc_module_encode_video(TCModule handle, + vframe_list_t *inframe, + vframe_list_t *outframe) +{ + return handle->klass->encode_video(&(handle->instance), + inframe, outframe); +} + +#ifdef HAVE_GCC_ATTRIBUTES +__attribute__((unused)) +#endif +static int tc_module_encode_audio(TCModule handle, + aframe_list_t *inframe, + aframe_list_t *outframe) +{ + return handle->klass->encode_audio(&(handle->instance), + inframe, outframe); +} + +#ifdef HAVE_GCC_ATTRIBUTES +__attribute__((unused)) +#endif +static int tc_module_decode_video(TCModule handle, + vframe_list_t *inframe, + vframe_list_t *outframe) +{ + return handle->klass->decode_video(&(handle->instance), + inframe, outframe); +} + +#ifdef HAVE_GCC_ATTRIBUTES +__attribute__((unused)) +#endif +static int tc_module_decode_audio(TCModule handle, + aframe_list_t *inframe, + aframe_list_t *outframe) +{ + return handle->klass->decode_audio(&(handle->instance), + inframe, outframe); +} + +#ifdef HAVE_GCC_ATTRIBUTES +__attribute__((unused)) +#endif +static int tc_module_filter_video(TCModule handle, + vframe_list_t *frame) +{ + return handle->klass->filter_video(&(handle->instance), frame); +} + +#ifdef HAVE_GCC_ATTRIBUTES +__attribute__((unused)) +#endif +static int tc_module_filter_audio(TCModule handle, + aframe_list_t *frame) +{ + return handle->klass->filter_audio(&(handle->instance), frame); +} + +#ifdef HAVE_GCC_ATTRIBUTES +__attribute__((unused)) +#endif +static int tc_module_multiplex(TCModule handle, + vframe_list_t *vframe, + aframe_list_t *aframe) +{ + return handle->klass->multiplex(&(handle->instance), vframe, aframe); +} + +#ifdef HAVE_GCC_ATTRIBUTES +__attribute__((unused)) +#endif +static int tc_module_demultiplex(TCModule handle, + vframe_list_t *vframe, + aframe_list_t *aframe) +{ + return handle->klass->demultiplex(&(handle->instance), vframe, aframe); +} + +#ifdef HAVE_GCC_ATTRIBUTES +__attribute__((unused)) +#endif +static const TCModuleInfo *tc_module_get_info(TCModule handle) +{ + return handle->klass->info; +} + +#ifdef HAVE_GCC_ATTRIBUTES +__attribute__((unused)) +#endif +static int tc_module_match(int codec, + TCModule handle, TCModule other) +{ + return tc_module_info_match(codec, + handle->klass->info, other->klass->info); +} + +#ifdef HAVE_GCC_ATTRIBUTES +__attribute__((unused)) +#endif +static void tc_module_show_info(TCModule handle, int verbose) +{ + tc_module_info_log(handle->klass->info, verbose); +} + +/* FIXME: that's just ugly. */ +#ifdef HAVE_GCC_ATTRIBUTES +__attribute__((unused)) +#endif +static void tc_module_pass_extradata(TCModule source, TCModule dest) +{ + if (source != NULL && dest != NULL) { + /* soft copy */ + dest->instance.extradata = source->instance.extradata; + dest->instance.extradata_size = source->instance.extradata_size; + } +} + + +/* factory data type. */ +typedef struct tcfactory_ *TCFactory; + +/************************************************************************* + * factory methods * + *************************************************************************/ + +/* + * tc_new_module_factory: + * initialize a module factory. This function will acquire all + * needed resources and set all things appropriately to make the + * factory ready for create module instances, loading plugins on + * demand if needed. + * + * Parameters: + * modpath: + * module base directory. The factory will look for + * transcode plugins to load if needed starting from this + * directory. + * Note that this must be a single directory. + * verbose: + * verbosiness level of factory. Control the quantity + * of informative messates to print out. + * Should be one of TC_INFO, TC_DEBUG... value. + * + * Return Value: + * A valid TCFactory if initialization was done + * succesfully, NULL otherwise. In latter case, a informative + * message is sent through tc_log*(). + * + * Side effects: + * uses tc_log*() internally. + * + * Preconditions: + * modpath NOT NULL; giving a NULL parameter will cause a + * graceful failure. + * + * Postconditions: + * factory initialized and ready to create TCModules. + */ +TCFactory tc_new_module_factory(const char *modpath, int verbose); + +/* + * tc_del_module_factory: + * finalize a module factory. Shutdowns the factory completely, + * cleaning up everything and unloading plugins. + * PLEASE NOTE: this function _CAN_ fail, notably if a plugin + * can't be unloaded cleanly (this usually happens because a plugin + * has still some live instances at finalization time). + * ALWAYS check the return value and take opportune countermeasures. + * At time of writing, a factory can't (and it's unlikely it will + * do) destroy all living instances automatically. + * + * Parameters: + * factory: factory handle to finalize. + * + * Return Value: + * 0 succesfull. + * -1 an error occurred (notified via tc_log*). + * + * Side effects: + * uses tc_log*() internally. + * + * Preconditions: + * given factory was already initialized. Trying to finalize a + * non-initialized factory causes undefined behaviour. + * + * Postconditions: + * all resources acquired by factory are released; no modules are + * loaded or avalaible, nor module instances are still floating around. + */ +int tc_del_module_factory(TCFactory factory); + +/* + * tc_new_module: + * using given factory, create a new module instance of the given type, + * belonging to given class, and initialize it with reasonnable + * defaults values. + * This function may load a plugin implicitely to fullfill the request, + * since plugins are loaded on demand of client code. + * The returned instance pointer must be released using + * tc_del_module (see below). + * The returned instance is ready to use with above tc_module_* macros, + * or in any way you like. + * + * PLEASE NOTE: this function automatically invokes module initialization + * method on given module. You should NOT do by yourself. + * + * Parameters: + * factory: use this factory instance to build the new module. + * modclass: class of module requested (filter, encoding, + * demultiplexing...). + * modname: name of module requested. + * media: media type for new module (TC_VIDEO, TC_AUDIO, TC_EXTRA) + * + * Return value: + * NULL: an error occurred, and notified via tc_log_*() + * valid handle to a new module instance otherwise. + * + * Side effects: + * uses tc_log*() internally. + * a plugin can be loaded (except for errors!) implicitely. + * + * Preconditions: + * given factory was already intialized. + * + * Postconditions: + * if succeeded, module ready to use by client code. + * + * Examples: + * if you want to load the "foobar" plugin, belonging to filter class, + * you should use a code like this: + * + * TCModule my_module = tc_new_module("filter", "foobar"); + */ +TCModule tc_new_module(TCFactory factory, + const char *modclass, const char *modname, int media); + +/* + * tc_del_module: + * destroy a module instance using given factory, unloading corrispondent + * plugin from factory if needed. + * This function release the maximum amount of resources possible + * acquired by a given module; since some resources (originating plugin) + * are shared between all instances, there is possible that some call + * doesn't release all resources. Anyway, si guaranted that all resources + * are released when all instances are destroyed. + * + * PLEASE NOTE: this function automatically invokes module finalization + * method on given module. You should'nt do by yourself. + * + * Parameters: + * factory: a factory handle, the same one used to create the module + * module: module instance to destroy. + * + * Return Value: + * 0 succesfull + * -1 an error occurred (notified via tc_log*). + * + * Side effects: + * uses tc_log*() internally. + * a plugin could be unloaded implicitely. + * + * Preconditions: + * factory already initialized. + * ***GIVEN MODULE WAS CREATED USING GIVEN FACTORY*** + * to violate this condition will case an undefined behaviour. + * At time of writing, factory *CANNOT* detect when this condition + * is violated. So be careful. + * + * given module instance was obtained using tc_new_module, + * applying this function to a module instances obtained in a + * different way causes undefined behaviour, most likely a memory + * corruption. + * + * Postconditions: + * resources belonging to instance are released (see above). + */ +int tc_del_module(TCFactory factory, TCModule module); + +/* + * tc_plugin_count: + * get the number of loaded plugins in a given factory. + * Used mainly for debug purposes. + * + * Parameters: + * factory: handle to factory to analyze. + * + * Return Value: + * the number of plugins loaded at the moment. + * + * Side effects: + * None + * + * Preconditions: + * Given factory was already initialized. + * To apply this function to an unitialized factory will cause + * an undefine dbehaviour + * + * Postconditions: + * None + */ +int tc_plugin_count(const TCFactory factory); + +/* + * tc_module_count: + * get the number of module created and still valid by a given + * factory. Used mainly for debug purposes. + * + * Parameters: + * factory: handle to factory to analyze. + * + * Return Value: + * the number of module created and not yet destroyed at the moment. + * + * Side effects: + * None + * + * Preconditions: + * Given factory was already initialized. + * To apply this function to an unitialized factory will cause + * an undefine dbehaviour + * + * Postconditions: + * None + */ +int tc_instance_count(const TCFactory factory); + +/* + * tc_compare_modules: + * compare two module (through it's handler) supposed to be the same + * type (class + name). Used mainly for debug purposes. + * + * This function *MUST* SCREW UP BADLY if internal checks + * are absoultely clean, so assert are used at this moment. + * + * Parameters: + * amod: handle to first module instance. + * bmod: handle to second module instance + * + * Return value: + * -1 totally different modules + * 0 same class (some shared data) + * +1 same module instance: the two handles point to same instance + * + * Side effects: + * client code can be abort()ed. + * + * Preconditions: + * both module handles must refer to valid modules. + * + * Postconditions: + * None + */ +int tc_compare_modules(const TCModule amod, const TCModule bmod); + +#endif /* TCMODULE_CORE_H */ diff --git a/debian/transcode/transcode-1.1.7/libtc/tcmodule-data.h b/debian/transcode/transcode-1.1.7/libtc/tcmodule-data.h new file mode 100644 index 00000000..ab8e4d47 --- /dev/null +++ b/debian/transcode/transcode-1.1.7/libtc/tcmodule-data.h @@ -0,0 +1,348 @@ +/* + * tcmodule-data.h -- transcode module system, take two: data types. + * (C) 2005-2010 - Francesco Romani <fromani -at- gmail -dot- com> + * + * This file is part of transcode, a video stream processing tool. + * + * transcode 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. + * + * transcode is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + + +/* + * this header file contains basic data types declarations for transcode's + * new module system (1.1.x and later). + * Should not be included directly, but doing this will not harm anything. + */ +#ifndef TCMODULE_DATA_H +#define TCMODULE_DATA_H + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include <stdint.h> +#include <stdlib.h> + +#include "framebuffer.h" +#include "transcode.h" +#include "tcmodule-info.h" + +#define TC_MODULE_VERSION_MAJOR 2 +#define TC_MODULE_VERSION_MINOR 0 +#define TC_MODULE_VERSION_MICRO 0 + +#define TC_MAKE_MOD_VERSION(MAJOR, MINOR, MICRO) \ + ((( 0UL & 0xFF) << 24) \ + |(((MAJOR) & 0xFF) << 16) \ + |(((MINOR) & 0xFF) << 8) \ + | ((MICRO) & 0xFF)) + +#define TC_MODULE_VERSION \ + TC_MAKE_MOD_VERSION(TC_MODULE_VERSION_MAJOR, \ + TC_MODULE_VERSION_MINOR, \ + TC_MODULE_VERSION_MICRO) + +/* + * allowed status transition chart: + * + * init configure + * +--------------+ -----> +-----------+ ------------> +--------------+ + * | module limbo | | [created] | | [configured] | + * +--------------+ <----- +-----------+ <----------- +--------------+ + * fini A stop | + * | | + * | | + * | any specific operation: | + * | encode_*, filter_*, | + * | multiplex, ... | + * | V + * `-------------- +-----------+ + * stop | [running] | + * +-----------+ + * + */ + +/* + * Data structure private for each instance. + * This is an almost-opaque structure. + * + * The main purpose of this structure is to let each module (class) + * to have it's private data, totally opaque to loader and to the + * client code. + * This structure also keep some accounting informations useful + * both for module code and for loader. Those informations are + * a module id, which identifies uniquely a given module instance + * in a given timespan, and a string representing the module 'type', + * a composition of it's class and specific name. + */ +typedef struct tcmoduleinstance_ TCModuleInstance; +struct tcmoduleinstance_ { + int id; /* instance id; */ + const char *type; /* packed class + name of module */ + uint32_t features; /* subset of enabled features for this instance */ + + void *userdata; /* opaque to factory, used by each module */ + + void *extradata; + size_t extradata_size; + /* + * extradata: + * opaque data needed by a module that should'nt be private. + * Used mainly into encoder->multiplexor communication. + * NOTE: + * I'don't see a better way to handle extradata (see encode_ffmpeg + * module) in current architecture. I don't want to stack modules + * (if encoder drives multiplexor can handle itself the extradata) + * nor add more operations and/or accessors. This way looks as the + * cleanest and cheapest to me. Suggestions welcome. -- FRomani. + */ + // FIXME: add status to enforce correct operation sequence? +}; + +/* can be shared between _all_ instances */ +typedef struct tcmoduleclass_ TCModuleClass; +struct tcmoduleclass_ { + uint32_t version; + + int id; /* opaque internal handle */ + + const TCModuleInfo *info; + + /* mandatory operations: */ + int (*init)(TCModuleInstance *self, uint32_t features); + int (*fini)(TCModuleInstance *self); + int (*configure)(TCModuleInstance *self, const char *options, vob_t *vob); + int (*stop)(TCModuleInstance *self); + int (*inspect)(TCModuleInstance *self, const char *param, const char **value); + + /* + * not-mandatory operations, a module doing something useful implements + * at least one of following. + */ + int (*encode_audio)(TCModuleInstance *self, + aframe_list_t *inframe, aframe_list_t *outframe); + int (*encode_video)(TCModuleInstance *self, + vframe_list_t *inframe, vframe_list_t *outframe); + int (*decode_audio)(TCModuleInstance *self, + aframe_list_t *inframe, aframe_list_t *outframe); + int (*decode_video)(TCModuleInstance *self, + vframe_list_t *inframe, vframe_list_t *outframe); + int (*filter_audio)(TCModuleInstance *self, aframe_list_t *frame); + int (*filter_video)(TCModuleInstance *self, vframe_list_t *frame); + int (*multiplex)(TCModuleInstance *self, + vframe_list_t *vframe, aframe_list_t *aframe); + int (*demultiplex)(TCModuleInstance *self, + vframe_list_t *vframe, aframe_list_t *aframe); +}; + +/************************************************************************** + * TCModuleClass operations documentation: * + ************************************************************************** + * + * init: + * initialize a module, acquiring all needed resources. + * A module must also be configure()d before to be used. + * An initialized, but unconfigured, module CAN'T DELIVER + * a proper result when a specific operation (encode, demultiplex) + * is requested. Request an operation in a initialized but unconfigured + * module will result in an undefined behaviour. + * Parameters: + * self: pointer to module instance to initialize. + * features: select feature of this module to initialize. + * Return Value: + * 0 succesfull. + * -1 error occurred. A proper message should be sent to user using + * tc_log*() + * Postconditions: + * Given module is ready to be configured. + * + * + * fini: + * finalize an initialized module, releasing all acquired resources. + * A finalized module MUST be re-initialized before any new usage. + * Parameters: + * self: pointer to module instance to finalize. + * Return Value: + * 0 succesfull. + * -1 error occurred. A proper message should be sent to user using + * tc_log*() + * Preconditions: + * module was already initialized. To finalize a uninitialized module + * will cause an undefined behaviour. + * An unconfigured module can be finalized safely. + * Postconditions: + * all resources acquired by given module are released. + * + * + * configure: + * setup a module using module specific options and required data + * (via `vob' structure). It is requested to configure a module + * before to be used safely to perform any specific operation. + * Trying to configure a non-initialized module will cause an + * undefined behaviour. + * Parameters: + * self: pointer to module instance to configure. + * options: string contaning module options. + * Syntax is fixed (see optstr), + * semantic is module-dependent. + * vob: pointer to vob structure. + * Return Value: + * 0 succesfull. + * -1 error occurred. A proper message should be sent to user using + * tc_log*() + * Preconditions: + * Given module was already initialized AND stopped. + * A module MUST be stop()ped before to be configured again, otherwise + * an undefined behaviour will occur (expect at least resource leaks). + * Postconditions: + * Given module is ready to perform any supported operation. + * + * + * stop: + * reset a module and prepare for reconfiguration or finalization. + * This means to flush buffers, close open files and so on, + * but NOT release the reseource needed by a module to work. + * Please note that this operation can do actions similar, but + * not equal, to `fini'. Also note that `stop' can be invoked + * zero or multiple times during the module lifetime, but + * `fini' WILL be invkoed one and only one time. + * Parameters: + * self: pointer to module instance to stop. + * Return Value: + * 0 succesfull. + * -1 error occurred. A proper message should be sent to user using + * tc_log*() + * Preconditions: + * Given module was already initialized. Try to (re)stop + * an unitialized module will cause an undefined behaviour. + * It's safe to stop an unconfigured module. + * Postconditions: + * Given module is ready to be reconfigured safely. + * + * + * inspect: + * expose the current value of an a tunable option in a module, + * represented as a string. + * Every module MUST support two special options: + * 'all': will return a packed, human-readable representation + * of ALL tunable parameters in a given module, or an + * empty string if module hasn't any tunable option. + * This string must be in the same form accepted by + * `configure' operation. + * 'help': will return a formatted, human-readable string + * with module overview, tunable options and explanation. + * Parameters: + * self: pointer to module instance to inspect. + * param: name of parameter to inspect + * value: when method succesfully returns, will point to a constant + * string (that MUST NOT be *free()d by calling code) + * containing the actual value of requested parameter. + * PLEASE NOTE that this value CAN change between + * invocations of this method. + * Return value: + * 0 succesfull. That means BOTH the request was honoured OR + * the requested parameter isn't known and was silently ignored. + * -1 INTERNAL error, reason will be tc_log*()'d out. + * Preconditions: + * module was already initialized. + * Inspecting a uninitialized module will cause an + * undefined behaviour. + * + * + * decode_{audio,video}: + * encode_{audio,video}: + * decode or encode a given audio/video frame, storing + * (de)compressed data into another frame. + * Specific module loaded implements various codecs. + * Parameters: + * self: pointer to module instance to use. + * inframe: pointer to {audio,video} frame data to decode/encode. + * outframe: pointer to {audio,videp} frame which will hold + * (un)compressed data. Must be != NULL + * Return Value: + * 0 succesfull. + * -1 error occurred. A proper message should be sent to user using + * tc_log*() + * Preconditions: + * module was already initialized AND configured. + * To use a uninitialized and/or unconfigured module + * for decoding/encoding will cause an undefined behaviour. + * outframe != NULL. + * + * SPECIAL NOTE FOR encode_audio operation: + * if a NULL input frame pointer is given, but a VALID (not NULL) + * output frame pointer is given as well, a flush operation will performed. + * This means that encoder will emit all buffered audio data, in order + * to complete an audio frame and avoid data truncation/loss in output. + * + * + * filter_{audio,video}: + * apply an in-place transformation to a given audio/video frame. + * Specific module loaded determines the action performend on + * given frame. + * Parameters: + * self: pointer to module instance to use. + * frame: pointer to {audio,video} frame data to elaborate. + * Return Value: + * 0 succesfull. + * -1 error occurred. A proper message should be sent to user using + * tc_log*() + * Preconditions: + * module was already initialized AND configured. + * To use a uninitialized and/or unconfigured module + * for filter will cause an undefined behaviour. + * + * + * multiplex: + * merge given encoded frames in output stream. + * Parameters: + * self: pointer to module instance to use. + * vframe: pointer to video frame to multiplex. + * if NULL, don't multiplex video for this invokation. + * aframe: pointer to audio frame to multiplex + * if NULL, don't multiplex audio for this invokation. + * Return value: + * -1 error occurred. A proper message should be sent to user using + * tc_log*(). + * >0 number of bytes writed for multiplexed frame(s). Can be + * (and usually is) different from the plain sum of sizes of + * encoded frames. + * Preconditions: + * module was already initialized AND configured. + * To use a uninitialized and/or unconfigured module + * for multiplex will cause an undefined behaviour. + * + * + * demultiplex: + * extract given encoded frames from input stream. + * Parameters: + * self: pointer to module instance to use. + * vframe: if not NULL, extract next video frame from input stream + * and store it here. + * aframe: if not NULL, extract next audio frame from input strema + * and store it here. + * Return value: + * -1 error occurred. A proper message should be sent to user using + * tc_log*(). + * >0 number of bytes readed for demultiplexed frame(s). Can be + * (and usually is) different from the plain sum of sizes of + * encoded frames. + * Preconditions: + * module was already initialized AND configured. + * To use a uninitialized and/or unconfigured module + * for demultiplex will cause an undefined behaviour. + * + */ + +#endif /* TCMODULE_DATA_H */ diff --git a/debian/transcode/transcode-1.1.7/libtc/tcmodule-info.h b/debian/transcode/transcode-1.1.7/libtc/tcmodule-info.h new file mode 100644 index 00000000..5787b6bf --- /dev/null +++ b/debian/transcode/transcode-1.1.7/libtc/tcmodule-info.h @@ -0,0 +1,212 @@ +/* + * tcmodule-info.h -- module data (capabilities) and helper functions. + * (C) 2005-2010 - Francesco Romani <fromani -at- gmail -dot- com> + * + * This file is part of transcode, a video stream processing tool. + * + * transcode 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. + * + * transcode is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + + +#ifndef TCMODULEINFO_H +#define TCMODULEINFO_H + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include <stdint.h> + +#include "tccodecs.h" +#include "tcformats.h" + +/* FIXME: move to a enum? */ +/* actions */ +#define TC_MODULE_FEATURE_NONE 0x00000000 + +#define TC_MODULE_FEATURE_FILTER 0x00000001 +#define TC_MODULE_FEATURE_DECODE 0x00000002 +#define TC_MODULE_FEATURE_ENCODE 0x00000004 +#define TC_MODULE_FEATURE_DEMULTIPLEX 0x00000020 +#define TC_MODULE_FEATURE_MULTIPLEX 0x00000040 +/* targets */ +#define TC_MODULE_FEATURE_VIDEO 0x00010000 +#define TC_MODULE_FEATURE_AUDIO 0x00020000 +#define TC_MODULE_FEATURE_EXTRA 0x00040000 + +#define TC_MODULE_FLAG_NONE 0x00000000 +#define TC_MODULE_FLAG_RECONFIGURABLE 0x00000001 +/* module can be reconfigured multiple times */ +#define TC_MODULE_FLAG_DELAY 0x00000002 +/* module require more than one input frame to work */ +#define TC_MODULE_FLAG_BUFFERING 0x00000004 +/* module require extra internal buffering + * (XXX: this flag will hopefully vanish soon) */ +#define TC_MODULE_FLAG_CONVERSION 0x00000010 +/* module requires an unavoidable csp conversion) + * (XXX: this flag will hopefully vanish soon) */ + +/* + * this structure will hold all the interesting informations + * both for user and for transcode itself of a given module. + */ +typedef struct tcmoduleinfo_ TCModuleInfo; +struct tcmoduleinfo_ { + uint32_t features; /* what this module can do? */ + uint32_t flags; /* quirks */ + + const char *name; + const char *version; + const char *description; + + /* + * the following two MUST point to an array of TC_CODEC_* + * terminated by a TC_CODEC_ERROR value + */ + const TCCodecID *codecs_in; + const TCCodecID *codecs_out; + + /* + * the following two MUST point to an array of TC_FORMAT_* + * terminated by a TC_FORMAT_ERROR value + */ + const TCFormatID *formats_in; + const TCFormatID *formats_out; +}; + +/* + * tc_module_info_match: + * scan the given informations about two modules, and tell if the + * two modules can be chained together using the given codec. + * + * Parameters: + * tc_codec: + * codec_id to be used. + * head: + * the first given module information structure; + * 'head' output is supposed to fit in 'tail' input. + * tail: + * the second given module information structure; + * tail' input is supposed to be given by 'head' output. + * + * Return value: + * 1 if 'head' can feed 'tail' safely, + * 0 otherwise + * + * Side effects: + * none + * + * Preconditions: + * none + * + * Postconditions: + * none + */ +int tc_module_info_match(int tc_codec, + const TCModuleInfo *head, + const TCModuleInfo *tail); + +/* + * tc_module_info_log: + * pretty-print the content of a given module information structure + * using functions of tc_log_*() family. + * + * Parameters: + * info: + * module information structure to dump + * verbose: + * level of detail of description, ranging to TC_QUIET to TC_STATS. + * Other values will be ignored + * + * Return value: + * none + * + * Side effects: + * some informations are printed using tc_log_*() + * + * Preconditions: + * 'verbose' must be in range TC_QUIET ... TC_STATS + * + * Postconditions: + * none + */ +void tc_module_info_log(const TCModuleInfo *info, int verbose); + +/* + * tc_module_info_copy: + * create an exact copy of 'src' in 'dst', allocating new fields. + * PLEASE NOTE: this is an 'hard' (real) copy, which makes two + * TCModuleInfo identical but indipendent. + * For a 'soft' (reference) copy, just memcpy() the two structures. + * + * Parameters: + * src: TCModuleInfo structure to be copied + * dst: pointer to structure that will hold the copy. + * + * Return value: + * 0 successfull + * -1 given (at least) a bad TCModuleInfo reference + * 1 not enough memory to perform a full copy + * + * Side effects: + * memory in 'dst' is allocated, usinc tc_* helpers, to hold data + * provided by 'src'. + * + * Preconditions: + * 'src' and 'dst' must point to valid TCModuleInfo structures. + * + * Postconditions: + * 'dst' is an exact copy of 'src'. + */ +int tc_module_info_copy(const TCModuleInfo *src, TCModuleInfo *dst); + +/* + * tc_module_info_free: + * free all resources (memory) acquired when copying a TCModuleInfo + * structure into another one. + * + * Parameters: + * info: structure copied to be freed + * + * Return value: + * none + * + * Side effects: + * none + * + * Preconditions: + * 'info' must be obtained as result of 'tc_module_info_copy' function, + * as 'dst' parameter. Applying this function to a structure obtained + * in a different way will cause an undefined behaviour, most likely + * a memory corruption or a crash + * + * Postconditions: + * all resources (memory) acquired by 'info' are released. + * + */ +void tc_module_info_free(TCModuleInfo *info); + +/*************************************************************************/ + +#endif /* TCMODULEINFO_H */ + +/* + * Local variables: + * c-file-style: "stroustrup" + * c-file-offsets: ((case-label . *) (statement-case-intro . *)) + * indent-tabs-mode: nil + * End: + * + * vim: expandtab shiftwidth=4: + */ diff --git a/debian/transcode/transcode-1.1.7/libtc/tcmodule-plugin.h b/debian/transcode/transcode-1.1.7/libtc/tcmodule-plugin.h new file mode 100644 index 00000000..95a9a5e0 --- /dev/null +++ b/debian/transcode/transcode-1.1.7/libtc/tcmodule-plugin.h @@ -0,0 +1,262 @@ +/* + * tcmodule-plugin.h -- transcode module system, take two: plugin parts. + * (C) 2005-2010 - Francesco Romani <fromani -at- gmail -dot- com> + * + * This file is part of transcode, a video stream processing tool. + * + * transcode 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. + * + * transcode is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + + +#ifndef TCMODULE_PLUGIN_H +#define TCMODULE_PLUGIN_H + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include <stdint.h> + +#include "tcmodule-info.h" +#include "tcmodule-data.h" + + +#define TC_MODULE_SELF_CHECK(self, WHERE) do { \ + if ((self) == NULL) { \ + tc_log_error(MOD_NAME, WHERE ": " # self " is NULL"); \ + return TC_ERROR; /* catch all for filter/encoders/decoders/(de)muxers */ \ + } \ +} while (0) + + +#define TC_HAS_FEATURE(flags, feat) \ + ((flags & (TC_MODULE_FEATURE_ ## feat)) ?1 :0) + +#ifdef HAVE_GCC_ATTRIBUTES +__attribute__((unused)) +#endif +static int tc_module_av_check(uint32_t flags) +{ + int i = 0; + + i += TC_HAS_FEATURE(flags, AUDIO); + i += TC_HAS_FEATURE(flags, VIDEO); + i += TC_HAS_FEATURE(flags, EXTRA); + + return i; +} + +#ifdef HAVE_GCC_ATTRIBUTES +__attribute__((unused)) +#endif +static int tc_module_cap_check(uint32_t flags) +{ + int i = 0; + + i += TC_HAS_FEATURE(flags, DECODE); + i += TC_HAS_FEATURE(flags, FILTER); + i += TC_HAS_FEATURE(flags, ENCODE); + i += TC_HAS_FEATURE(flags, MULTIPLEX); + i += TC_HAS_FEATURE(flags, DEMULTIPLEX); + + return i; +} + +#undef TC_HAS_FEATURE + + +#define TC_MODULE_INIT_CHECK(self, FEATURES, feat) do { \ + int j = tc_module_cap_check((feat)); \ + \ + if ((!((FEATURES) & TC_MODULE_FEATURE_MULTIPLEX) \ + && !((FEATURES) & TC_MODULE_FEATURE_DEMULTIPLEX)) \ + && (tc_module_av_check((feat)) > 1)) { \ + tc_log_error(MOD_NAME, "unsupported stream types for" \ + " this module instance"); \ + return TC_ERROR; \ + } \ + \ + if (j != 0 && j != 1) { \ + tc_log_error(MOD_NAME, "feature request mismatch for" \ + " this module instance (req=%i)", j); \ + return TC_ERROR; \ + } \ + /* is perfectly fine to request to do nothing */ \ + if ((feat != 0) && ((FEATURES) & (feat))) { \ + (self)->features = (feat); \ + } else { \ + tc_log_error(MOD_NAME, "this module does not support" \ + " requested feature"); \ + return TC_ERROR; \ + } \ +} while (0) + +/* + * autogeneration macros for generic init/fini pair + * looks like generic pair is needed often that expected; + * In future module system revision, maybe they will be + * moved into core. + */ + +#define TC_MODULE_GENERIC_INIT(MODNAME, MODDATA) \ + static int MODNAME ## _init(TCModuleInstance *self, uint32_t features) \ + { \ + MODDATA *pd = NULL; \ + \ + TC_MODULE_SELF_CHECK(self, "init"); \ + TC_MODULE_INIT_CHECK(self, MOD_FEATURES, features); \ + \ + pd = tc_malloc(sizeof(MODDATA)); \ + if (pd == NULL) { \ + tc_log_error(MOD_NAME, "init: out of memory!"); \ + return TC_ERROR; \ + } \ + \ + self->userdata = pd; \ + \ + if (verbose) { \ + tc_log_info(MOD_NAME, "%s %s", MOD_VERSION, MOD_CAP); \ + } \ + \ + return TC_OK; \ + } + +#define TC_MODULE_GENERIC_FINI(MODNAME) \ + static int MODNAME ## _fini(TCModuleInstance *self) \ + { \ + TC_MODULE_SELF_CHECK(self, "fini"); \ + \ + tc_free(self->userdata); \ + self->userdata = NULL; \ + return TC_OK; \ + } + +/* + * autogeneration macro for TCModuleInfo descriptor + */ +#define TC_MODULE_INFO(PREFIX) \ +static const TCModuleInfo PREFIX ## _info = { \ + .features = MOD_FEATURES, \ + .flags = MOD_FLAGS, \ + .name = MOD_NAME, \ + .version = MOD_VERSION, \ + .description = MOD_CAP, \ + .codecs_in = PREFIX ## _codecs_in, \ + .codecs_out = PREFIX ## _codecs_out, \ + .formats_in = PREFIX ## _formats_in, \ + .formats_out = PREFIX ## _formats_out \ +} + +/* please note the MISSING trailing comma */ +#define TC_MODULE_CLASS_HEAD(PREFIX) \ + .version = TC_MODULE_VERSION, \ + .info = & ( PREFIX ## _info) + + +/* + * autogeneration for supported codecs/multiplexors + */ +#define TC_MODULE_FILTER_FORMATS(PREFIX) \ +static const TCFormatID PREFIX ## _formats_in[] = { TC_FORMAT_ERROR }; \ +static const TCFormatID PREFIX ## _formats_out[] = { TC_FORMAT_ERROR } + +#define TC_MODULE_CODEC_FORMATS(PREFIX) \ +static const TCFormatID PREFIX ## _formats_in[] = { TC_FORMAT_ERROR }; \ +static const TCFormatID PREFIX ## _formats_out[] = { TC_FORMAT_ERROR } + +#define TC_MODULE_MPLEX_FORMATS_CODECS(PREFIX) \ +static const TCCodecID PREFIX ## _codecs_out[] = { TC_CODEC_ERROR }; \ +static const TCFormatID PREFIX ## _formats_in[] = { TC_FORMAT_ERROR } + +#define TC_MODULE_DEMUX_FORMATS_CODECS(PREFIX) \ +static const TCCodecID PREFIX ## _codecs_in = { TC_CODEC_ERROR }; \ +static const TCFormatID PREFIX ## _formats_out[] = { TC_FORMAT_ERROR } + +/* + * plugin entry point prototype + */ +const TCModuleClass *tc_plugin_setup(void); + +#define TC_MODULE_ENTRY_POINT(MODNAME) \ + extern const TCModuleClass *tc_plugin_setup(void) \ + { \ + return &( MODNAME ## _class); \ + } + + +/* TODO: unify in a proper way OLDINTERFACE and OLDINTERFACE_M */ +#define TC_FILTER_OLDINTERFACE(name) \ + /* Old-fashioned module interface. */ \ + static TCModuleInstance mod; \ + \ + int tc_filter(frame_list_t *frame, char *options) \ + { \ + if (frame->tag & TC_FILTER_INIT) { \ + if (name ## _init(&mod, TC_MODULE_FEATURE_FILTER) < 0) { \ + return TC_ERROR; \ + } \ + return name ## _configure(&mod, options, tc_get_vob()); \ + \ + } else if (frame->tag & TC_FILTER_GET_CONFIG) { \ + return name ## _get_config(&mod, options); \ + \ + } else if (frame->tag & TC_FILTER_CLOSE) { \ + if (name ## _stop(&mod) < 0) { \ + return TC_ERROR; \ + } \ + return name ## _fini(&mod); \ + } \ + \ + return name ## _process(&mod, frame); \ + } + + + +#define TC_FILTER_OLDINTERFACE_INSTANCES 128 + +/* FIXME: + * this uses the filter ID as an index--the ID can grow + * arbitrarily large, so this needs to be fixed + */ +#define TC_FILTER_OLDINTERFACE_M(name) \ + /* Old-fashioned module interface. */ \ + static TCModuleInstance mods[TC_FILTER_OLDINTERFACE_INSTANCES]; \ + \ + int tc_filter(frame_list_t *frame, char *options) \ + { \ + TCModuleInstance *mod = &mods[frame->filter_id]; \ + \ + if (frame->tag & TC_FILTER_INIT) { \ + tc_log_info(MOD_NAME, "instance #%i", frame->filter_id); \ + if (name ## _init(mod, TC_MODULE_FEATURE_FILTER) < 0) { \ + return TC_ERROR; \ + } \ + return name ## _configure(mod, options, tc_get_vob()); \ + \ + } else if (frame->tag & TC_FILTER_GET_CONFIG) { \ + return name ## _get_config(mod, options); \ + \ + } else if (frame->tag & TC_FILTER_CLOSE) { \ + if (name ## _stop(mod) < 0) { \ + return TC_ERROR; \ + } \ + return name ## _fini(mod); \ + } \ + \ + return name ## _process(mod, frame); \ + } + + + +#endif /* TCMODULE_PLUGIN_H */ diff --git a/debian/transcode/transcode-1.1.7/libtc/tcmodule.c b/debian/transcode/transcode-1.1.7/libtc/tcmodule.c new file mode 100644 index 00000000..ca2d59ff --- /dev/null +++ b/debian/transcode/transcode-1.1.7/libtc/tcmodule.c @@ -0,0 +1,1015 @@ +/* + * tcmodule.c -- transcode module system, take two. + * (C) 2005-2010 - Francesco Romani <fromani -at- gmail -dot- com> + * + * This file is part of transcode, a video stream processing tool. + * + * transcode 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. + * + * transcode is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + + +#include "config.h" + +#ifdef HAVE_DLFCN_H +#include <dlfcn.h> +#else +# ifdef OS_DARWIN +# include "libdldarwin/dlfcn.h" +# endif +#endif + +#include <string.h> + +#include "libtc.h" +#include "tccodecs.h" +#include "tcmodule-data.h" +#include "tcmodule-core.h" +#include "transcode.h" + +#define TC_FACTORY_MAX_HANDLERS (16) +#define MOD_TYPE_MAX_LEN (TC_BUF_MIN * 2) + +#define tc_module_init(module, features) \ + (module)->klass->init(&((module)->instance), features) +#define tc_module_fini(module) \ + (module)->klass->fini(&((module)->instance)) + +/* module entry point */ +typedef const TCModuleClass* (*TCModuleEntry)(void); + +typedef enum { + TC_DESCRIPTOR_FREE = 0, /* free to use */ + TC_DESCRIPTOR_CREATED, /* reserved, but not yet registered */ + TC_DESCRIPTOR_DONE, /* ok, all donw and ready to run */ +} TCHandleStatus; + +typedef struct tcmoduledescriptor_ TCModuleDescriptor; +struct tcmoduledescriptor_ { + const char *type; /* packed class + name using make_modtype below */ + void *so_handle; /* used by dl*() stuff */ + TCHandleStatus status; + TCModuleInfo info; + + /* main copy of module class data. + * all instance pointers will refer to this. */ + TCModuleClass klass; + + int ref_count; /* how many instances are floating around? */ +}; + +struct tcfactory_ { + const char *mod_path; /* base directory for plugin search */ + int verbose; + + TCModuleDescriptor descriptors[TC_FACTORY_MAX_HANDLERS]; + int descriptor_count; + + int instance_count; +}; + +/************************************************************************* + * dummy/fake default module class. Always fails complaining loudly. * + * Using this as default, every module class has already valid * + * (but sometimes useless) pointers to every method. * + *************************************************************************/ + +#define DUMMY_HEAVY_CHECK(self, method_name) do { \ + if (self != NULL) { \ + tc_log_warn(self->type, "critical: module doesn't provide" \ + " %s method", method_name); \ + } else { \ + tc_log_error(__FILE__, "critical: %s method missing AND bad" \ + " instance pointer", method_name); \ + } \ +} while (0) + +#define DUMMY_CHECK(self, method_name) do { \ + if (self != NULL) { \ + tc_log_warn(self->type, \ + "module doesn't provide %s method", method_name); \ + } else { \ + tc_log_error(__FILE__, "%s method missing AND bad" \ + " instance pointer", method_name); \ + } \ +} while (0) + + +static int dummy_init(TCModuleInstance *self, uint32_t features) +{ + DUMMY_HEAVY_CHECK(self, "initialization"); + return TC_ERROR; +} + +static int dummy_fini(TCModuleInstance *self) +{ + DUMMY_HEAVY_CHECK(self, "finalization"); + return TC_ERROR; +} + +static int dummy_configure(TCModuleInstance *self, + const char *options, vob_t *vob) +{ + DUMMY_HEAVY_CHECK(self, "configuration"); + return TC_ERROR; +} + +static int dummy_stop(TCModuleInstance *self) +{ + DUMMY_HEAVY_CHECK(self, "stopping"); + return TC_ERROR; +} + +static int dummy_inspect(TCModuleInstance *self, + const char *param, const char **value) +{ + DUMMY_HEAVY_CHECK(self, "inspect"); + return TC_ERROR; +} + +static int dummy_encode_video(TCModuleInstance *self, + vframe_list_t *inframe, + vframe_list_t *outframe) +{ + DUMMY_CHECK(self, "encode_video"); + return TC_ERROR; +} + +static int dummy_encode_audio(TCModuleInstance *self, + aframe_list_t *inframe, + aframe_list_t *outframe) +{ + DUMMY_CHECK(self, "encode_audio"); + return TC_ERROR; +} + +static int dummy_decode_video(TCModuleInstance *self, + vframe_list_t *inframe, + vframe_list_t *outframe) +{ + DUMMY_CHECK(self, "decode_video"); + return TC_ERROR; +} + +static int dummy_decode_audio(TCModuleInstance *self, + aframe_list_t *inframe, + aframe_list_t *outframe) +{ + DUMMY_CHECK(self, "decode_audio"); + return TC_ERROR; +} + +static int dummy_filter_video(TCModuleInstance *self, + vframe_list_t *frame) +{ + DUMMY_CHECK(self, "filter_video"); + return TC_ERROR; +} + +static int dummy_filter_audio(TCModuleInstance *self, + aframe_list_t *frame) +{ + DUMMY_CHECK(self, "filter_audio"); + return TC_ERROR; +} + +static int dummy_multiplex(TCModuleInstance *self, + vframe_list_t *vframe, aframe_list_t *aframe) +{ + DUMMY_CHECK(self, "multiplex"); + return TC_ERROR; +} + +static int dummy_demultiplex(TCModuleInstance *self, + vframe_list_t *vframe, aframe_list_t *aframe) +{ + DUMMY_CHECK(self, "demultiplex"); + return TC_ERROR; +} + +#undef DUMMY_HEAVY_CHECK +#undef DUMMY_CHECK + +static const TCCodecID dummy_codecs_in[] = { + TC_CODEC_ANY, TC_CODEC_ERROR +}; +static const TCCodecID dummy_codecs_out[] = { + TC_CODEC_ANY, TC_CODEC_ERROR +}; +static const TCFormatID dummy_formats_in[] = { + TC_FORMAT_RAW, TC_FORMAT_ERROR +}; +static const TCFormatID dummy_formats_out[] = { + TC_FORMAT_RAW, TC_FORMAT_ERROR +}; + +static TCModuleInfo dummy_info = { + .features = TC_MODULE_FEATURE_NONE, + .flags = TC_MODULE_FLAG_NONE, + .name = "dummy", + .version = "internal fake module class", + .description = "can't do anyhing", + .codecs_in = dummy_codecs_in, + .codecs_out = dummy_codecs_out, + .formats_in = dummy_formats_in, + .formats_out = dummy_formats_out +}; + +static const TCModuleClass dummy_class = { + .id = 0, + + .info = &dummy_info, + + .init = dummy_init, + .fini = dummy_fini, + .configure = dummy_configure, + .inspect = dummy_inspect, + .stop = dummy_stop, + + .encode_audio = dummy_encode_audio, + .encode_video = dummy_encode_video, + .decode_audio = dummy_decode_audio, + .decode_video = dummy_decode_video, + .filter_audio = dummy_filter_audio, + .filter_video = dummy_filter_video, + + .multiplex = dummy_multiplex, + .demultiplex = dummy_demultiplex +}; + +/************************************************************************* + * private helpers * + *************************************************************************/ + +/* + * translate_modclass: + * validate a module class name, represented by a given string. + * + * Parameters: + * modclass: a class nome to validate. + * Return Value: + * TC_MOFULE_FEATURE_* correspondent. + */ +static uint32_t translate_modclass(const char *modclass) +{ + uint32_t ret = TC_MODULE_FEATURE_NONE; + + if (modclass != NULL) { + if (!strcmp(modclass, "filter")) { + ret = TC_MODULE_FEATURE_FILTER; + } else if (!strcmp(modclass, "demultiplex") + || !strcmp(modclass, "demux")) { + ret = TC_MODULE_FEATURE_DEMULTIPLEX; + } else if (!strcmp(modclass, "decode")) { + ret = TC_MODULE_FEATURE_DECODE; + } else if (!strcmp(modclass, "encode")) { + ret = TC_MODULE_FEATURE_ENCODE; + } else if (!strcmp(modclass, "multiplex") + || !strcmp(modclass, "mplex")) { + ret = TC_MODULE_FEATURE_MULTIPLEX; + } + } + return ret; +} + +/* FIXME: writeme */ +static uint32_t translate_media(int media) +{ + uint32_t ret = TC_MODULE_FEATURE_NONE; + + switch (media) { + case TC_VIDEO: + ret = TC_MODULE_FEATURE_VIDEO; + break; + case TC_AUDIO: + ret = TC_MODULE_FEATURE_AUDIO; + break; + case TC_EXTRA: + ret = TC_MODULE_FEATURE_EXTRA; + break; + } + return ret; +} + +/* + * TCModuleDescriptorIter: + * generic iterator function on factory descriptors. + * In some different contexts, a iterator can be applied on all module + * descriptors in a given factory. Specific iterator functions can do + * arbitrary actions on descriptor data. + * See below to get some usage examples. + * + * Parameters: + * desc: pointer to a TCModuleDescriptor. + * userdata: opaque pointer to function-specific data. + * Return Value: + * 0 -> keep on going + * <0 -> stop iteration and return code verbatim + * >0 -> stop iteration and return current iteration index + * Side effects: + * Arbitrary, defined by specific function. + * Preconditions: + * given factory (but isn't guaranteed that also descriptors are) already + * initialized and contains valid data. + */ +typedef int (*TCModuleDescriptorIter)(TCModuleDescriptor *desc, void *userdata); + +/* + * tc_foreach_descriptor: + * apply given iterator with given data to all internal descriptors, + * *both used and unused*. + * + * Parameters: + * factory: factory instance to use + * iterator: iterator to apply at factory descriptors + * userdata: opaque data to pass to iterator along with each descriptor + * index: pointer to an integer. If not NULL, will be filled + * with index of last descriptor elaborated + * Return Value: + * return code of the last execution of iterator. + * Side effects: + * None (see specific descriptor for this). + * Postconditions: + * If return value is 0, given iteratr wass applied to *all* + * descriptors in factory. + */ +static int tc_foreach_descriptor(TCFactory factory, + TCModuleDescriptorIter iterator, + void *userdata, + int *index) +{ + int ret, i = 0; + + if (!factory || !iterator) { + return -1; + } + + for (i = 0; i < TC_FACTORY_MAX_HANDLERS; i++) { + ret = iterator(&(factory->descriptors[i]), userdata); + if (ret != 0) { + break; + } + } + /* iteration stopped, so we mark the interruption point */ + if (ret != 0 && index != NULL) { + *index = i; + } + return ret; +} + +/* + * descriptor_something: some iterator functions + */ + +/* + * descriptor_match_modtype: + * verify the match for a given descriptor and a given module type. + * + * Parameters: + * desc: descriptor to verify + * modtype_: module type to look for. + * Return Value: + * 1 if given descriptor has given module type, + * 0 succesfull. + * -1 if a given parameter is bogus. + */ +static int descriptor_match_modtype(TCModuleDescriptor *desc, + void *modtype_) +{ + char *modtype = modtype_; + if (!desc || !modtype) { + return -1; + } + if (desc->status == TC_DESCRIPTOR_DONE + && desc->type != NULL + && (strcmp(desc->type, modtype) == 0)) { + /* found it! */ + return 1; + } + return 0; +} + +/* + * descriptor_is_free: + * verify the match for a given descriptor is an unitialized one. + * + * Parameters: + * desc: descriptor to verify + * unused: dummy parameter to achieve API conformancy. + * Return Value: + * 1 if given descriptor is a free one (uninitialized), + * 0 succesfull. + * -1 if a given parameter is bogus. + */ +static int descriptor_is_free(TCModuleDescriptor *desc, void *unused) +{ + if (!desc) { + return -1; + } + if (desc->status == TC_DESCRIPTOR_FREE) { + return 1; + } + return 0; +} + +/* + * descriptor_init: + * initialize a plugin descriptor with valid defaults. + * + * Parameters: + * desc: descriptor to initialize. + * unused: dummy parameter to achieve API conformancy. + * Return Value: + * 0 succesfull. + * -1 if a given parameter is bogus. + */ +static int descriptor_init(TCModuleDescriptor *desc, void *unused) +{ + if (!desc) { + return -1; + } + + desc->status = TC_DESCRIPTOR_FREE; + memcpy(&(desc->info), &dummy_info, sizeof(TCModuleInfo)); + desc->klass.info = &(desc->info); + desc->type = NULL; + desc->so_handle = NULL; + desc->ref_count = 0; + + return 0; +} + +/* + * descriptor_fini: + * finalize a plugin descriptor, releasing all acquired + * resources. + * + * Parameters: + * desc: descriptor to finalize. + * unused: dummy parameter to achieve API conformancy. + * Return Value: + * 1 if given descriptor has still some live instances around, + * 0 succesfull. + * -1 if a given parameter is bogus. + * Side effects: + * A plugin will be released and unloaded (via dlclose()). + */ +static int descriptor_fini(TCModuleDescriptor *desc, void *unused) +{ + if (!desc) { + return -1; + } + + /* can't finalize an descriptor with some living instances still around */ + if (desc->ref_count > 0) { + return 1; + } + + if (desc->status == TC_DESCRIPTOR_DONE) { + if (desc->type != NULL) { + tc_free((void*)desc->type); /* avoid const warning */ + desc->type = NULL; + } + if (desc->so_handle != NULL) { + dlclose(desc->so_handle); + desc->so_handle = NULL; + } + desc->status = TC_DESCRIPTOR_FREE; + } + return 0; +} + +/* just a thin wrapper to adapt API */ +static int find_by_modtype(TCFactory factory, const char *modtype) +{ + int ret, id; + ret = tc_foreach_descriptor(factory, descriptor_match_modtype, + (void*)modtype, &id); + /* ret >= 1 -> found something */ + return (ret >= 1) ?id : -1; +} + +/* just a thin wrapper to adapt API */ +static int find_first_free_descriptor(TCFactory factory) +{ + int ret, id; + ret = tc_foreach_descriptor(factory, descriptor_is_free, NULL, &id); + /* ret >= 1 -> found something */ + return (ret >= 1) ?id : -1; +} + +/* Yeah, is that simple. Yet. ;) */ +static void make_modtype(char *buf, size_t bufsize, + const char *modclass, const char *modname) +{ + tc_snprintf(buf, bufsize, "%s:%s", modclass, modname); +} + +/* + * tc_module_class_copy: + * copy a module class into another one. Can perform + * a soft (reference) copy or a hard (full) one. + * Only non-null function pointer to plugin operations + * will be copied. + * soft copy: make the two classes points to same real data. + * hard copy: make two independent copies duplicating the data. + * + * Parameters: + * klass: source class to be copied. + * nklass: class destionation of copy. + * soft_copy: boolean flag: if !0 do a soft copy, + * do an hard one otherwise. + * Return Value: + * 0 successfull + * -1 given (at least) a bad TCModuleClass reference + * 1 not enough memory to perform a full copy + * Postconditions: + * destination class is a copy of source class. + */ + +#define COPY_IF_NOT_NULL(field) do { \ + if (klass->field != NULL) { \ + nklass->field = klass->field; \ + } \ +} while (0) + +static int tc_module_class_copy(const TCModuleClass *klass, + TCModuleClass *nklass) +{ + if (!klass || !nklass) { + /* 'impossible' condition */ + tc_log_error(__FILE__, "bad module class reference for setup: %s%s", + (!klass) ?"plugin class" :"", + (!nklass) ?"core class" :""); + return -1; + } + + if (!klass->init || !klass->fini || !klass->configure || !klass->stop + || !klass->inspect) { + /* should'nt happen */ + tc_log_error(__FILE__, "can't setup a module class without " + "one or more mandatory methods"); + return -1; + } + + /* register only method really provided by given class */ + nklass->init = klass->init; + nklass->fini = klass->fini; + nklass->configure = klass->configure; + nklass->stop = klass->stop; + nklass->inspect = klass->inspect; + + nklass->info = klass->info; + + COPY_IF_NOT_NULL(encode_audio); + COPY_IF_NOT_NULL(encode_video); + COPY_IF_NOT_NULL(decode_audio); + COPY_IF_NOT_NULL(decode_video); + COPY_IF_NOT_NULL(filter_audio); + COPY_IF_NOT_NULL(filter_video); + COPY_IF_NOT_NULL(multiplex); + COPY_IF_NOT_NULL(demultiplex); + + return 0; +} + +#undef COPY_IF_NOT_NULL + +/************************************************************************* + * module versioning helpers * + *************************************************************************/ + +struct tcmodver { + int reserved; + int major; + int minor; + int micro; +}; + +static void expand_version(uint32_t version, struct tcmodver *modver) +{ + modver->reserved = (version & 0xFF000000) >> 24; + modver->major = (version & 0x00FF0000) >> 16; + modver->minor = (version & 0x0000FF00) >> 8; + modver->micro = (version & 0x000000FF); +} + +/* + * tc_module_version_matches: + * check compatibilty between the transcode core version and + * a supplied module version. + * Only a major version mismatch gives incompatibility (...yet). + * + * Parameters: + * modversion: the module version being checked. + * Return Value: + * 0 if module is incompatible with transcode core + * !0 otherwise. + * Side Effects: + * in case of incompatibilty (of any degree), messages are + * tc_log()'d out. + */ +static int tc_module_version_matches(uint32_t modversion) +{ + struct tcmodver ver_core, ver_mod; + + expand_version(TC_MODULE_VERSION, &ver_core); + expand_version(modversion, &ver_mod); + + if (ver_core.reserved != ver_mod.reserved) { + tc_log_error(__FILE__, "internal version error"); + return 0; + } + + /* different major versions are a no-no */ + if (ver_core.major != ver_mod.major) { + tc_log_error(__FILE__, "incompatible module version " + "(core=%i.%i.%i|module=%i.%i.%i)", + ver_core.major, ver_core.minor, ver_core.micro, + ver_mod.major, ver_mod.minor, ver_mod.micro); + return 0; + } + /* if you use different minor version, you've to know that */ + if (ver_core.minor != ver_mod.minor) { + tc_log_error(__FILE__, "old module version " + "(core=%i.%i.%i|module=%i.%i.%i)", + ver_core.major, ver_core.minor, ver_core.micro, + ver_mod.major, ver_mod.minor, ver_mod.micro); + /* still compatible! */ + } + /* different micro version are ok'd silently */ + return 1; +} + + +/************************************************************************* + * main private helpers: _load and _unload * + *************************************************************************/ + +#define RETURN_IF_INVALID_STRING(str, msg, errval) do { \ + if (!str || !strlen(str)) { \ + tc_log_error(__FILE__, msg); \ + return (errval); \ + } \ +} while (0) + +#define RETURN_IF_INVALID_QUIET(val, errval) do { \ + if (!(val)) { \ + return (errval); \ + } \ +} while (0) + +#define TC_LOG_DEBUG(fp, level, format, ...) do { \ + if ((fp)->verbose >= level) { \ + tc_log_info(__FILE__, format, __VA_ARGS__); \ + } \ +} while (0) + + +/* + * tc_load_module: + * load in a given factory a plugin needed for a given module. + * please note that here 'plugin' and 'module' terms are used + * interchangeably since a given module name from a given module + * class usually (almost always, even if such constraint doesn't + * exist) originates from a plugin with same class and same name. + * + * In other words, doesn't exist (yet, nor is planned) a plugin + * that can generate more than one module and/or more than one + * module class + * + * Parameters: + * factory: module factory to loads module in + * modclass: class of plugin to load + * modname: name of plugin to load + * Return Value: + * >= 0 identifier (slot) of newly loaded plugin + * -1 error occcurred (and notified via tc_log*()) + * Side effects: + * a plugin (.so) is loaded into process + * Preconditions: + * none. + * Postconditions: + * none + */ +static int tc_load_module(TCFactory factory, + const char *modclass, const char *modname) +{ + int id = -1, ret = -1; + char full_modpath[PATH_MAX]; + char modtype[MOD_TYPE_MAX_LEN]; + TCModuleEntry modentry = NULL; + TCModuleDescriptor *desc = NULL; + const TCModuleClass *nclass; + + /* 'impossible' conditions */ + RETURN_IF_INVALID_STRING(modclass, "empty module class", -1); + RETURN_IF_INVALID_STRING(modname, "empty module name", -1); + + make_modtype(modtype, PATH_MAX, modclass, modname); + tc_snprintf(full_modpath, PATH_MAX, "%s/%s_%s.so", + factory->mod_path, modclass, modname); + + id = find_first_free_descriptor(factory); + if (id == -1) { + /* should'nt happen */ + tc_log_error(__FILE__, "already loaded the maximum number " + "of modules (%i)", TC_FACTORY_MAX_HANDLERS); + return -1; + } + TC_LOG_DEBUG(factory, TC_DEBUG, "using slot %i for plugin '%s'", + id, modtype); + desc = &(factory->descriptors[id]); + desc->ref_count = 0; + + desc->so_handle = dlopen(full_modpath, RTLD_GLOBAL | RTLD_NOW); + if (!desc->so_handle) { + TC_LOG_DEBUG(factory, TC_INFO, "can't load module '%s'; reason: %s", + modtype, dlerror()); + goto failed_dlopen; + } + desc->type = tc_strdup(modtype); + if (!desc->type) { + goto failed_strdup; + } + desc->status = TC_DESCRIPTOR_CREATED; + + /* soft copy is enough here, since information will be overwritten */ + tc_module_class_copy(&dummy_class, &(desc->klass)); + + modentry = dlsym(desc->so_handle, "tc_plugin_setup"); + if (!modentry) { + TC_LOG_DEBUG(factory, TC_INFO, "module '%s' doesn't have new style" + " entry point", modtype); + goto failed_setup; + } + nclass = modentry(); + + if (!tc_module_version_matches(nclass->version)) { + /* reason already tc_log'd out */ + goto failed_setup; + } + + ret = tc_module_class_copy(nclass, &(desc->klass)); + + if (ret != 0) { + /* should'nt happen */ + tc_log_error(__FILE__, "failed class registration for module '%s'", + modtype); + goto failed_setup; + } + + desc->klass.id = id; /* enforce class/descriptor id */ + desc->status = TC_DESCRIPTOR_DONE; + factory->descriptor_count++; + + return id; + +failed_setup: + desc->status = TC_DESCRIPTOR_FREE; + tc_free((void*)desc->type); /* avoid const warning */ +failed_strdup: + dlclose(desc->so_handle); +failed_dlopen: + return -1; +} + +#define CHECK_VALID_ID(id, where) do { \ + if (id < 0 || id > TC_FACTORY_MAX_HANDLERS) { \ + if (factory->verbose >= TC_DEBUG) { \ + tc_log_error(__FILE__, "%s: invalid id (%i)", where, id); \ + } \ + return -1; \ + } \ +} while (0) + +/* + * tc_unload_module: + * unload a given (by id) plugin from given factory. + * This means that module belonging to such plugin is no longer + * avalaible from given factory, unless, of course, reloading such + * plugin. + * + * Parameters: + * factory: a module factory + * id: id of plugin to unload + * Return Value: + * 0 plugin unloaded correctly + * != 0 error occcurred (and notified via tc_log*()) + * Side effects: + * a plugin (.so) is UNloaded from process + * Preconditions: + * reference count for given plugin is zero. + * This means that no modules instances created by such plugin are + * still active. + * Postconditions: + * none + */ +static int tc_unload_module(TCFactory factory, int id) +{ + int ret = 0; + TCModuleDescriptor *desc = NULL; + + CHECK_VALID_ID(id, "tc_unload_module"); + desc = &(factory->descriptors[id]); + + if (desc->ref_count > 0) { + TC_LOG_DEBUG(factory, TC_DEBUG, "can't unload a module with active" + " ref_count (id=%i, ref_count=%i)", + desc->klass.id, desc->ref_count); + return 1; + } + + ret = descriptor_fini(desc, NULL); + if (ret == 0) { + factory->descriptor_count--; + return 0; + } + return ret; +} + +/************************************************************************* + * implementation of exported functions * + *************************************************************************/ + +TCFactory tc_new_module_factory(const char *modpath, int verbose) +{ + TCFactory factory = NULL; + RETURN_IF_INVALID_STRING(modpath, "empty module path", NULL); + + factory = tc_zalloc(sizeof(struct tcfactory_)); + RETURN_IF_INVALID_QUIET(factory, NULL); + + factory->mod_path = modpath; + factory->verbose = verbose; + factory->descriptor_count = 0; + factory->instance_count = 0; + + tc_foreach_descriptor(factory, descriptor_init, NULL, NULL); + + return factory; +} + +int tc_del_module_factory(TCFactory factory) +{ + RETURN_IF_INVALID_QUIET(factory, 1); + + tc_foreach_descriptor(factory, descriptor_fini, NULL, NULL); + + if (factory->descriptor_count > 0) { + /* should'nt happpen */ + tc_log_warn(__FILE__, "left out %i module descriptors", + factory->descriptor_count); + return -1; + } + + tc_free(factory); + return 0; +} + +TCModule tc_new_module(TCFactory factory, + const char *modclass, const char *modname, + int media) +{ + char modtype[MOD_TYPE_MAX_LEN]; + uint32_t flags = translate_modclass(modclass); + int id = -1, ret; + TCModule module = NULL; + + RETURN_IF_INVALID_QUIET(factory, NULL); + if (flags == TC_MODULE_FEATURE_NONE) { + TC_LOG_DEBUG(factory, TC_INFO, "unknown module class '%s'", + modclass); + return NULL; + } + + make_modtype(modtype, MOD_TYPE_MAX_LEN, modclass, modname); + TC_LOG_DEBUG(factory, TC_DEBUG, "trying to load '%s'", modtype); + id = find_by_modtype(factory, modtype); + if (id == -1) { + /* module type not already known */ + TC_LOG_DEBUG(factory, TC_STATS, "plugin not found for '%s'," + " loading...", modtype); + id = tc_load_module(factory, modclass, modname); + if (id == -1) { + /* load failed, give up */ + return NULL; + } + } + TC_LOG_DEBUG(factory, TC_DEBUG, "module descriptor found: id %i", id); + + module = tc_zalloc(sizeof(struct tcmodule_)); + module->instance.type = factory->descriptors[id].type; + module->instance.id = factory->instance_count + 1; + module->klass = &(factory->descriptors[id].klass); + + ret = tc_module_init(module, flags|translate_media(media)); + if (ret != 0) { + TC_LOG_DEBUG(factory, TC_DEBUG, "initialization of '%s' failed" + " (code=%i)", modtype, ret); + tc_free(module); + return NULL; + } + + factory->descriptors[id].ref_count++; + factory->instance_count++; + TC_LOG_DEBUG(factory, TC_DEBUG, "module created: type='%s'" + " instance id=(%i)", module->instance.type, + module->instance.id); + TC_LOG_DEBUG(factory, TC_STATS, "descriptor ref_count=(%i) instances" + " so far=(%i)", factory->descriptors[id].ref_count, + factory->instance_count); + + return module; +} + +int tc_del_module(TCFactory factory, TCModule module) +{ + int ret = 0, id = -1; + + RETURN_IF_INVALID_QUIET(factory, 1); + RETURN_IF_INVALID_QUIET(module, -1); + + id = module->klass->id; + CHECK_VALID_ID(id, "tc_del_module"); + + ret = tc_module_fini(module); + if (ret != 0) { + TC_LOG_DEBUG(factory, TC_DEBUG, "finalization of '%s' failed" + " (code=%i)", module->instance.type, ret); + return ret; + } + tc_free(module); + + factory->instance_count--; + factory->descriptors[id].ref_count--; + if (factory->descriptors[id].ref_count == 0) { + ret = tc_unload_module(factory, id); + } + return ret; +} + +/************************************************************************* + * Debug helpers. * + *************************************************************************/ + +int tc_plugin_count(const TCFactory factory) +{ + RETURN_IF_INVALID_QUIET(factory, -1); + return factory->descriptor_count; +} + +int tc_instance_count(const TCFactory factory) +{ + RETURN_IF_INVALID_QUIET(factory, -1); + return factory->instance_count; +} + + +#include <assert.h> + +int tc_compare_modules(const TCModule amod, const TCModule bmod) +{ + assert(amod != NULL && bmod != NULL); + + if ((amod == bmod) || (amod->instance.id == bmod->instance.id)) { + return 1; + } + + if (strcmp(amod->instance.type, bmod->instance.type) == 0) { + /* some internal sanity checks. + * assert()s are used here because those conditions + * WILL NOT *NEVER* BE FALSE! + * otherwise something _*really*_ evil is going on + */ + assert(amod->klass != NULL && bmod->klass != NULL); + assert(amod->klass == bmod->klass); + assert(amod->klass->id == bmod->klass->id); + assert(amod->klass->info == bmod->klass->info); + /* we should check method pointers as well? */ + return 0; + } + return -1; +} + +/*************************************************************************/ + +/* + * Local variables: + * c-file-style: "stroustrup" + * c-file-offsets: ((case-label . *) (statement-case-intro . *)) + * indent-tabs-mode: nil + * End: + * + * vim: expandtab shiftwidth=4: + */ diff --git a/debian/transcode/transcode-1.1.7/libtc/tcmoduleinfo.c b/debian/transcode/transcode-1.1.7/libtc/tcmoduleinfo.c new file mode 100644 index 00000000..92b2dcbc --- /dev/null +++ b/debian/transcode/transcode-1.1.7/libtc/tcmoduleinfo.c @@ -0,0 +1,207 @@ +/* + * tcmoduleinfo.c -- module informations (capabilities) and helper functions. + * (C) 2005-2010 - Francesco Romani <fromani -at- gmail -dot- com> + * + * This file is part of transcode, a video stream processing tool. + * + * transcode 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. + * + * transcode is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + + +#include "libtc.h" +#include "tcmodule-info.h" +#include "transcode.h" + +#include <string.h> + +#define HAVE_FEATURE(info, feat) \ + ((info)->features & (TC_MODULE_FEATURE_ ## feat)) + +int tc_module_info_match(int tc_codec, + const TCModuleInfo *head, const TCModuleInfo *tail) +{ + int found = 0; + int i = 0, j = 0; + /* we need a pair of valid references to go further */ + if (head == NULL || tail == NULL) { + return 0; + } + /* + * a multiplexor module can be chained with nothing, + * it must be placed at the end of the chain; reversed + * for demulitplexor module. + */ + if (HAVE_FEATURE(head, MULTIPLEX) || HAVE_FEATURE(tail, DEMULTIPLEX)) { + return 0; + } + /* format kind compatibility check */ + if ((HAVE_FEATURE(head, VIDEO) && !HAVE_FEATURE(tail, VIDEO)) + || (HAVE_FEATURE(head, AUDIO) && !HAVE_FEATURE(tail, AUDIO))) { + return 0; + } + + /* + * we look only for the first compatible match, not for the best one. + * Yet. + */ + for (i = 0; !found && tail->codecs_in[i] != TC_CODEC_ERROR; i++) { + for (j = 0; !found && head->codecs_out[j] != TC_CODEC_ERROR; j++) { + /* trivial case: exact match */ + if (tc_codec == head->codecs_out[j] + && head->codecs_out[j] == tail->codecs_in[i]) { + /* triple fit */ + found = 1; + } + if ((head->codecs_out[j] == tail->codecs_in[i] + || head->codecs_out[j] == TC_CODEC_ANY) + && TC_CODEC_ANY == tc_codec) { + found = 1; + } + if ((tc_codec == head->codecs_out[j] + || tc_codec == TC_CODEC_ANY) + && TC_CODEC_ANY == tail->codecs_in[i]) { + found = 1; + } + if ((tail->codecs_in[i] == tc_codec + || tail->codecs_in[i] == TC_CODEC_ANY) + && TC_CODEC_ANY == head->codecs_out[j]) { + found = 1; + } + } + } + return found; +} + +#undef HAVE_FEATURE + + +static void codecs_to_string(const TCCodecID *codecs, char *buffer, + size_t bufsize, const char *fallback_string) +{ + int found = 0; + int i = 0; + + if (buffer == NULL || bufsize < TC_BUF_LINE) { + return; + } + + buffer[0] = '\0'; + + for (i = 0; codecs[i] != TC_CODEC_ERROR; i++) { + const char *codec = tc_codec_to_string(codecs[i]); + if (codec != NULL) { + strlcat(buffer, codec, bufsize); + strlcat(buffer, " ", bufsize); + found = 1; + } + } + if (!found) { + strlcpy(buffer, fallback_string, bufsize); + } +} + +void tc_module_info_log(const TCModuleInfo *info, int verbose) +{ + char buffer[TC_BUF_LINE]; + + if (info == NULL) { + return; + } + if (info->name == NULL + || (info->version == NULL || info->description == NULL)) { + tc_log_error(__FILE__, "missing critical information for module"); + return; + } + + if (verbose >= TC_STATS) { + tc_log_info(info->name, "description:\n%s", info->description); + } + + if (verbose >= TC_DEBUG) { + if (info->features == TC_MODULE_FEATURE_NONE) { + strlcpy(buffer, "none (this shouldn't happen!", sizeof(buffer)); + } else { + tc_snprintf(buffer, sizeof(buffer), "%s%s%s", + (info->features & TC_MODULE_FEATURE_VIDEO) ?"video " :"", + (info->features & TC_MODULE_FEATURE_AUDIO) ?"audio " :"", + (info->features & TC_MODULE_FEATURE_EXTRA) ?"extra" :""); + } + tc_log_info(info->name, "can handle : %s", buffer); + + if (info->features == TC_MODULE_FEATURE_NONE) { + strlcpy(buffer, "nothing (this shouldn't happen!", sizeof(buffer)); + } else { + tc_snprintf(buffer, sizeof(buffer), "%s%s%s", + (info->features & TC_MODULE_FEATURE_FILTER) + ?"filtering " :"", + (info->features & TC_MODULE_FEATURE_ENCODE) + ?"encoding " :"", + (info->features & TC_MODULE_FEATURE_MULTIPLEX) + ?"multiplexing" :""); + } + tc_log_info(info->name, "can do : %s", buffer); + + if (info->flags == TC_MODULE_FLAG_NONE) { + strlcpy(buffer, "none", sizeof(buffer)); + } else { + tc_snprintf(buffer, sizeof(buffer), "%s%s%s%s", + (info->flags & TC_MODULE_FLAG_RECONFIGURABLE) + ?"reconfigurable " :"", + (info->flags & TC_MODULE_FLAG_DELAY) + ?"delay " :"", + (info->flags & TC_MODULE_FLAG_BUFFERING) + ?"buffering " :"", + (info->flags & TC_MODULE_FLAG_CONVERSION) + ?"conversion " :""); + } + tc_log_info(info->name, "flags : %s", buffer); + } + + if (verbose >= TC_INFO) { + const char *str = (info->features & TC_MODULE_FEATURE_MULTIPLEX) + ?"a media stream" :"nothing"; + codecs_to_string(info->codecs_in, buffer, sizeof(buffer), str); + tc_log_info(info->name, "accepts : %s", buffer); + + codecs_to_string(info->codecs_out, buffer, TC_BUF_LINE, str); + tc_log_info(info->name, "produces : %s", buffer); + } +} + +void tc_module_info_free(TCModuleInfo *info) +{ + if (info != NULL) { + /* + * void* casts to silence warning from gcc 4.x (free requires void*, + * argument is const something* + */ + tc_free((void*)info->name); + tc_free((void*)info->version); + tc_free((void*)info->description); + tc_free((void*)info->codecs_in); + tc_free((void*)info->codecs_out); + } +} + +/*************************************************************************/ + +/* + * Local variables: + * c-file-style: "stroustrup" + * c-file-offsets: ((case-label . *) (statement-case-intro . *)) + * indent-tabs-mode: nil + * End: + * + * vim: expandtab shiftwidth=4: + */ diff --git a/debian/transcode/transcode-1.1.7/libtc/tctimer.c b/debian/transcode/transcode-1.1.7/libtc/tctimer.c new file mode 100644 index 00000000..aceb02b5 --- /dev/null +++ b/debian/transcode/transcode-1.1.7/libtc/tctimer.c @@ -0,0 +1,136 @@ +/* + * tctimer.c -- simple timer code implementation for transcode. + * (C) 2006-2010 - Francesco Romani <fromani -at- gmail -dot- com> + * + * This file is part of transcode, a video stream processing tool. + * + * transcode 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. + * + * transcode is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + + +#include "config.h" + +#ifndef HAVE_GETTIMEOFDAY +# error "this module REQUIRES gettimeofday presence!" +#endif + +#include <sys/time.h> +#include <time.h> +#include <errno.h> + +#include "tctimer.h" +#include "libtc.h" + +/* + * Internal time representation: + * XXX WRITEME + */ + +/*************************************************************************/ +/* utilities */ + +static uint64_t tc_timeval_to_microsecs(const struct timeval *tv) +{ + return (tv->tv_sec * 1000000 + tv->tv_usec); +} + +uint64_t tc_gettime(void) +{ + struct timeval tv; + + gettimeofday(&tv, NULL); + + return tc_timeval_to_microsecs(&tv); +} + +/*************************************************************************/ +/* generics */ + +/*************************************************************************/ + +static uint64_t tc_timer_generic_elapsed(TCTimer *timer) +{ + uint64_t r = 0, t = tc_gettime(); + r = t - timer->last_time; + timer->last_time = t; + return r; +} + +/*************************************************************************/ +/* timer-specific code */ + +/*************************************************************************/ + +static int tc_timer_soft_fini(TCTimer *timer) +{ + return 0; /* no internal state -> nothing to finalize */ +} + +static int tc_timer_soft_sleep(TCTimer *timer, uint64_t amount) +{ + struct timespec ts, tr; + int ret; + + ts.tv_sec = amount / 1000000; + ts.tv_nsec = (amount % 1000000) * 1000; + + do { + ret = nanosleep(&ts, &tr); + if (ret == -1) { + if (errno != EINTR) { + /* report fault */ + break; + } else { + /* reload */ + ts.tv_sec = tr.tv_sec; + ts.tv_nsec = tr.tv_nsec; + } + } + } while (ret != 0); + return ret; +} + +/*************************************************************************/ +/* entry points */ + +/*************************************************************************/ + +int tc_timer_init_soft(TCTimer *timer, uint16_t frequency) +{ + int ret = -1; + + if (timer != NULL) { + /* frequency: ignored, we relies on nanosleep() */ + timer->last_time = tc_gettime(); + + timer->elapsed = tc_timer_generic_elapsed; + timer->sleep = tc_timer_soft_sleep; + timer->fini = tc_timer_soft_fini; + + ret = 0; + } + return ret; +} + +/*************************************************************************/ + +/* + * Local variables: + * c-file-style: "stroustrup" + * c-file-offsets: ((case-label . *) (statement-case-intro . *)) + * indent-tabs-mode: nil + * End: + * + * vim: expandtab shiftwidth=4: + */ diff --git a/debian/transcode/transcode-1.1.7/libtc/tctimer.h b/debian/transcode/transcode-1.1.7/libtc/tctimer.h new file mode 100644 index 00000000..ee6aecbd --- /dev/null +++ b/debian/transcode/transcode-1.1.7/libtc/tctimer.h @@ -0,0 +1,154 @@ +/* + * tctimer.h -- simple timer code for transcode. + * (C) 2006-2010 - Francesco Romani <fromani -at- gmail -dot- com> + * + * This file is part of transcode, a video stream processing tool. + * + * transcode 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. + * + * transcode is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + + +#ifndef TCTIMER_H +#define TCTIMER_H + +#include "config.h" + +#include <stdint.h> + + + +typedef union tctimestamp_ TCTimestamp; +union tctimestamp_ { + uint64_t u; + double d; +}; + + +/* + * Quick Summary: + * + * At time of writing, {import,demultiplex}_x11 is the only + * piece of transcode that uses timers. + * I've chosen to factorize such code and put here on libtc + * in order to make it more visible and to promote reviews. + * + * This code may look overengineered, I'd like to make it generic + * in order to easily introduce further, platform-specific, timing + * support (i.e. Linux RTC). They aren't yet ready since the overall + * X11 source support is still on work. More will follow soon. + * + */ + +/* + * Time unit used: microseconds (1e-6) + * It's EXPECTED that client code requires a timing resolution at least + * one order of magnitude LESS precise than internal resolution, I.e. + * milliseconds. + */ + + +/* + * tc_gettime: + * return the current time using the best avalaible time source. + * + * Parameters: + * None. + * Return Value: + * time units elapsed since EPOCH. + */ +uint64_t tc_gettime(void); + +/*************************************************************************/ + + +typedef struct tctimer_ TCTimer; +struct tctimer_ { + uint64_t last_time; + /* timestamp of last timer reading */ + + int (*fini)(TCTimer *timer); + uint64_t (*elapsed)(TCTimer *timer); + int (*sleep)(TCTimer *timer, uint64_t amount); +}; + +int tc_timer_init_soft(TCTimer *timer, uint16_t frequency); + +/* + * tc_timer_fini: + * finalize given timer by freeing all resources acquired. + * + * Parameters: + * timer: timer to finalize. + * Return Value: + * 0 : succesfull. + * -1: error. + */ +#ifdef HAVE_GCC_ATTRIBUTES +__attribute__((unused)) +#endif +static int tc_timer_fini(TCTimer *timer) +{ + return timer->fini(timer); +} + +/* + * tc_timer_elapsed: + * read timer status and get the amount of time units + * elapsed *SINCE LAST READ*. + * First read automagically delivers right results, + * so client code hasn't to worry about this. + * + * Parameters: + * timer: timer to read. + * Return Value: + * time units elapsed since last reading. + * Side Effects: + * Update internal timestamp. + */ +#ifdef HAVE_GCC_ATTRIBUTES +__attribute__((unused)) +#endif +static uint64_t tc_timer_elapsed(TCTimer *timer) +{ + return timer->elapsed(timer); +} + +/* + * tc_timer_sleep: + * blocks caller (thread) for given amount of time units. + * + * *PLEASE NOTE* + * that this function CAN'T guarantee STRICT observancy of + * sleeping time. It is very likely that blocking time is + * different (usually greater) than wanted. + * Providing more guarantees involve deeper interaction with + * host OS that is out of the scope of this code, yet. + * + * Parameters: + * timer: timer to use. + * amount: (try to) block caller for this amount of time units. + * Return Value: + * 0: succesfully. Blocked for given amount of time units + * (see note above) + * -1: failed: an error has caused premature return. + */ +#ifdef HAVE_GCC_ATTRIBUTES +__attribute__((unused)) +#endif +static int tc_timer_sleep(TCTimer *timer, uint64_t amount) +{ + return timer->sleep(timer, amount); +} + +#endif /* TCTIMER_H */ diff --git a/debian/transcode/transcode-1.1.7/libtc/xio.h b/debian/transcode/transcode-1.1.7/libtc/xio.h new file mode 100644 index 00000000..1183156b --- /dev/null +++ b/debian/transcode/transcode-1.1.7/libtc/xio.h @@ -0,0 +1,55 @@ +/* + * xio.h + * + * Copyright (C) Lukas Hejtmanek - January 2004 + * + * This file is part of transcode, a video stream processing tool + * + * transcode 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, or (at your option) + * any later version. + * + * transcode is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Make; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#ifndef LIBTC_XIO_H +#define LIBTC_XIO_H + +#ifdef HAVE_IBP + +#include <sys/types.h> +#include <sys/stat.h> + +int xio_open(const char *pathname, int flags, ...); +ssize_t xio_read(int fd, void *buf, size_t count); +ssize_t xio_write(int fd, const void *buf, size_t count); +int xio_ftruncate(int fd, off_t length); +off_t xio_lseek(int fd, off_t offset, int whence); +int xio_close(int fd); +int xio_fstat(int fd, struct stat *buf); +int xio_lstat(const char *filename, struct stat *buf); +int xio_stat(const char *filename, struct stat *buf); +int xio_rename(const char *oldpath, const char *newpath); +#else /* not HAVE_IBP */ +#define xio_open open +#define xio_read read +#define xio_write write +#define xio_ftruncate ftruncate +#define xio_lseek lseek +#define xio_close close +#define xio_fstat fstat +#define xio_lstat lstat +#define xio_stat stat +#define xio_rename rename +#endif /* HAVE_IBP */ + +#endif /* LIBTC_XIO_H */ |
