rem-0.4.7/0000755000175100017510000000000012640750470013074 5ustar rkrishnanrkrishnanrem-0.4.7/mk/0000755000175100017510000000000012640750470013503 5ustar rkrishnanrkrishnanrem-0.4.7/mk/Doxyfile0000644000175100017510000002124412436611306015211 0ustar rkrishnanrkrishnan# Doxyfile 1.4.7 #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- PROJECT_NAME = librem PROJECT_NUMBER = 0.4.0 OUTPUT_DIRECTORY = ../rem-dox CREATE_SUBDIRS = NO OUTPUT_LANGUAGE = English #USE_WINDOWS_ENCODING = NO BRIEF_MEMBER_DESC = YES REPEAT_BRIEF = YES ABBREVIATE_BRIEF = "The $name class" \ "The $name widget" \ "The $name file" \ is \ provides \ specifies \ contains \ represents \ a \ an \ the ALWAYS_DETAILED_SEC = NO INLINE_INHERITED_MEMB = NO FULL_PATH_NAMES = NO STRIP_FROM_PATH = STRIP_FROM_INC_PATH = SHORT_NAMES = NO JAVADOC_AUTOBRIEF = YES MULTILINE_CPP_IS_BRIEF = NO #DETAILS_AT_TOP = NO INHERIT_DOCS = YES SEPARATE_MEMBER_PAGES = NO TAB_SIZE = 8 ALIASES = OPTIMIZE_OUTPUT_FOR_C = YES OPTIMIZE_OUTPUT_JAVA = NO #BUILTIN_STL_SUPPORT = NO DISTRIBUTE_GROUP_DOC = NO SUBGROUPING = YES #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- EXTRACT_ALL = NO EXTRACT_PRIVATE = NO EXTRACT_STATIC = NO EXTRACT_LOCAL_CLASSES = YES EXTRACT_LOCAL_METHODS = NO HIDE_UNDOC_MEMBERS = YES HIDE_UNDOC_CLASSES = YES HIDE_FRIEND_COMPOUNDS = NO HIDE_IN_BODY_DOCS = NO INTERNAL_DOCS = NO CASE_SENSE_NAMES = YES HIDE_SCOPE_NAMES = NO SHOW_INCLUDE_FILES = YES INLINE_INFO = YES SORT_MEMBER_DOCS = YES SORT_BRIEF_DOCS = NO SORT_BY_SCOPE_NAME = NO GENERATE_TODOLIST = YES GENERATE_TESTLIST = YES GENERATE_BUGLIST = YES GENERATE_DEPRECATEDLIST= YES ENABLED_SECTIONS = MAX_INITIALIZER_LINES = 30 SHOW_USED_FILES = YES FILE_VERSION_FILTER = #--------------------------------------------------------------------------- # configuration options related to warning and progress messages #--------------------------------------------------------------------------- QUIET = YES WARNINGS = YES WARN_IF_UNDOCUMENTED = YES WARN_IF_DOC_ERROR = YES WARN_NO_PARAMDOC = YES WARN_FORMAT = "$file:$line: $text" WARN_LOGFILE = #--------------------------------------------------------------------------- # configuration options related to the input files #--------------------------------------------------------------------------- INPUT = include src FILE_PATTERNS = *.c \ *.h \ *.dox RECURSIVE = YES EXCLUDE = test.c EXCLUDE_SYMLINKS = NO EXCLUDE_PATTERNS = */.svn/* EXAMPLE_PATH = EXAMPLE_PATTERNS = * EXAMPLE_RECURSIVE = NO IMAGE_PATH = INPUT_FILTER = FILTER_PATTERNS = FILTER_SOURCE_FILES = NO #--------------------------------------------------------------------------- # configuration options related to source browsing #--------------------------------------------------------------------------- SOURCE_BROWSER = YES INLINE_SOURCES = NO STRIP_CODE_COMMENTS = YES REFERENCED_BY_RELATION = YES REFERENCES_RELATION = YES #REFERENCES_LINK_SOURCE = YES #USE_HTAGS = NO VERBATIM_HEADERS = YES #--------------------------------------------------------------------------- # configuration options related to the alphabetical class index #--------------------------------------------------------------------------- ALPHABETICAL_INDEX = YES COLS_IN_ALPHA_INDEX = 5 IGNORE_PREFIX = #--------------------------------------------------------------------------- # configuration options related to the HTML output #--------------------------------------------------------------------------- GENERATE_HTML = YES HTML_OUTPUT = html HTML_FILE_EXTENSION = .html HTML_HEADER = HTML_FOOTER = HTML_STYLESHEET = GENERATE_HTMLHELP = NO CHM_FILE = HHC_LOCATION = GENERATE_CHI = NO BINARY_TOC = NO TOC_EXPAND = NO DISABLE_INDEX = NO ENUM_VALUES_PER_LINE = 4 GENERATE_TREEVIEW = NO TREEVIEW_WIDTH = 250 #--------------------------------------------------------------------------- # configuration options related to the LaTeX output #--------------------------------------------------------------------------- GENERATE_LATEX = NO LATEX_OUTPUT = latex LATEX_CMD_NAME = latex MAKEINDEX_CMD_NAME = makeindex COMPACT_LATEX = NO PAPER_TYPE = a4wide EXTRA_PACKAGES = LATEX_HEADER = PDF_HYPERLINKS = NO USE_PDFLATEX = NO LATEX_BATCHMODE = NO LATEX_HIDE_INDICES = NO #--------------------------------------------------------------------------- # configuration options related to the RTF output #--------------------------------------------------------------------------- GENERATE_RTF = NO RTF_OUTPUT = rtf COMPACT_RTF = NO RTF_HYPERLINKS = NO RTF_STYLESHEET_FILE = RTF_EXTENSIONS_FILE = #--------------------------------------------------------------------------- # configuration options related to the man page output #--------------------------------------------------------------------------- GENERATE_MAN = NO MAN_OUTPUT = man MAN_EXTENSION = .3 MAN_LINKS = NO #--------------------------------------------------------------------------- # configuration options related to the XML output #--------------------------------------------------------------------------- GENERATE_XML = NO XML_OUTPUT = xml XML_PROGRAMLISTING = YES #--------------------------------------------------------------------------- # configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- GENERATE_AUTOGEN_DEF = NO #--------------------------------------------------------------------------- # configuration options related to the Perl module output #--------------------------------------------------------------------------- GENERATE_PERLMOD = NO PERLMOD_LATEX = NO PERLMOD_PRETTY = YES PERLMOD_MAKEVAR_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the preprocessor #--------------------------------------------------------------------------- ENABLE_PREPROCESSING = YES MACRO_EXPANSION = YES EXPAND_ONLY_PREDEF = YES SEARCH_INCLUDES = YES INCLUDE_PATH = include INCLUDE_FILE_PATTERNS = PREDEFINED = HAVE_INTTYPES_H HAVE_INET6 HAVE_STDBOOL_H EXPAND_AS_DEFINED = SKIP_FUNCTION_MACROS = YES #--------------------------------------------------------------------------- # Configuration::additions related to external references #--------------------------------------------------------------------------- TAGFILES = GENERATE_TAGFILE = ALLEXTERNALS = NO EXTERNAL_GROUPS = YES PERL_PATH = /usr/bin/perl #--------------------------------------------------------------------------- # Configuration options related to the dot tool #--------------------------------------------------------------------------- CLASS_DIAGRAMS = YES HIDE_UNDOC_RELATIONS = YES HAVE_DOT = YES CLASS_GRAPH = YES COLLABORATION_GRAPH = YES GROUP_GRAPHS = YES UML_LOOK = NO TEMPLATE_RELATIONS = NO INCLUDE_GRAPH = YES INCLUDED_BY_GRAPH = YES #CALL_GRAPH = YES todo: disabled to run faster #CALLER_GRAPH = YES GRAPHICAL_HIERARCHY = YES DIRECTORY_GRAPH = YES DOT_IMAGE_FORMAT = png DOT_PATH = DOTFILE_DIRS = #MAX_DOT_GRAPH_WIDTH = 1024 #MAX_DOT_GRAPH_HEIGHT = 1024 #MAX_DOT_GRAPH_DEPTH = 1000 DOT_TRANSPARENT = NO DOT_MULTI_TARGETS = NO GENERATE_LEGEND = YES DOT_CLEANUP = YES #--------------------------------------------------------------------------- # Configuration::additions related to the search engine #--------------------------------------------------------------------------- SEARCHENGINE = NO rem-0.4.7/mk/symbian/0000755000175100017510000000000012640750470015145 5ustar rkrishnanrkrishnanrem-0.4.7/mk/symbian/rem.mmp0000644000175100017510000000214011713036660016436 0ustar rkrishnanrkrishnan/** * @file rem.mmp Symbian makefile for librem * * Copyright (C) 2010 Creytiv.com */ TARGET rem.lib TARGETTYPE lib TARGETPATH system\libs UID 0x10000fd3 0x200112FF #ifdef EKA2 VENDORID 0 CAPABILITY NetworkServices #endif MACRO HAVE_SYS_TIME_H MACRO HAVE_UNISTD_H MACRO HAVE_ACTSCHED #ifndef EKA2 SOURCEPATH . SOURCE dll.cpp #endif SOURCEPATH ..\..\src\aubuf SOURCE aubuf.c SOURCEPATH ..\..\src\aufile SOURCE aufile.c SOURCE wave.c SOURCEPATH ..\..\src\auresamp SOURCE resamp.c SOURCEPATH ..\..\src\autone SOURCE tone.c SOURCEPATH ..\..\src\g711 SOURCE g711.c SOURCEPATH ..\..\src\fir SOURCE fir.c SOURCEPATH ..\..\src\vid SOURCE fmt.c SOURCE frame.c SOURCEPATH ..\..\src\vidconv SOURCE vconv.c USERINCLUDE . ..\..\include SYSTEMINCLUDE \epoc32\include SYSTEMINCLUDE \epoc32\include\libc \epoc32\include\re SYSTEMINCLUDE ..\..\include #ifndef EKA2 LIBRARY estlib.lib euser.lib LIBRARY esock.lib insock.lib #endif EXPORTUNFROZEN rem-0.4.7/mk/symbian/bld.inf0000644000175100017510000000205011722465662016407 0ustar rkrishnanrkrishnan/** * @file bld.inf Symbian build information * * Copyright (C) 2010 Creytiv.com */ PRJ_EXPORTS ..\..\include\rem.h \epoc32\include\rem\rem.h ..\..\include\rem_au.h \epoc32\include\rem\rem_au.h ..\..\include\rem_aubuf.h \epoc32\include\rem\rem_aubuf.h ..\..\include\rem_audio.h \epoc32\include\rem\rem_audio.h ..\..\include\rem_aufile.h \epoc32\include\rem\rem_aufile.h ..\..\include\rem_aumix.h \epoc32\include\rem\rem_aumix.h ..\..\include\rem_auresamp.h \epoc32\include\rem\rem_auresamp.h ..\..\include\rem_autone.h \epoc32\include\rem\rem_autone.h ..\..\include\rem_dsp.h \epoc32\include\rem\rem_dsp.h ..\..\include\rem_fir.h \epoc32\include\rem\rem_fir.h ..\..\include\rem_g711.h \epoc32\include\rem\rem_g711.h ..\..\include\rem_vid.h \epoc32\include\rem\rem_vid.h ..\..\include\rem_vidconv.h \epoc32\include\rem\rem_vidconv.h ..\..\include\rem_video.h \epoc32\include\rem\rem_video.h ..\..\include\rem_vidmix.h \epoc32\include\rem\rem_vidmix.h PRJ_MMPFILES rem.mmp rem-0.4.7/mk/win32/0000755000175100017510000000000012640750470014445 5ustar rkrishnanrkrishnanrem-0.4.7/mk/win32/rem.vcproj0000644000175100017510000000774011713036660016463 0ustar rkrishnanrkrishnan rem-0.4.7/util/0000755000175100017510000000000012640750470014051 5ustar rkrishnanrkrishnanrem-0.4.7/util/genfir.py0000644000175100017510000000073111546443317015701 0ustar rkrishnanrkrishnan#!/usr/bin/python import scipy.signal TAPS = 31 CUTOFF = 8000.0 # Hz SRATE = 16000.0 # Hz cutoff = CUTOFF / SRATE coeffs = scipy.signal.firwin(TAPS, cutoff) print "/*" print " * FIR filter with cutoff %dHz, samplerate %dHz" % (CUTOFF, SRATE) print " */" print "static const int16_t fir_lowpass[%d] = {" % (TAPS) i = 0 for c in coeffs: v = int(c * 32768.0) print " %5d," % (v), i += 1 if not (i % 8): print "\n" , print "" print "};" rem-0.4.7/Makefile0000644000175100017510000000627412634535506014551 0ustar rkrishnanrkrishnan# # Makefile # # Copyright (C) 2010 Creytiv.com # # Master version number VER_MAJOR := 0 VER_MINOR := 4 VER_PATCH := 7 PROJECT := rem VERSION := 0.4.7 OPT_SPEED := 1 LIBRE_MK := $(shell [ -f ../re/mk/re.mk ] && \ echo "../re/mk/re.mk") ifeq ($(LIBRE_MK),) LIBRE_MK := $(shell [ -f /usr/share/re/re.mk ] && \ echo "/usr/share/re/re.mk") endif ifeq ($(LIBRE_MK),) LIBRE_MK := $(shell [ -f /usr/local/share/re/re.mk ] && \ echo "/usr/local/share/re/re.mk") endif include $(LIBRE_MK) # List of modules MODULES += fir MODULES += g711 MODULES += aubuf aufile auresamp autone MODULES += au auconv ifneq ($(HAVE_LIBPTHREAD),) MODULES += aumix vidmix endif MODULES += vid vidconv LIBS += -lm INSTALL := install ifeq ($(DESTDIR),) PREFIX := /usr/local else PREFIX := /usr endif ifeq ($(LIBDIR),) LIBDIR := $(PREFIX)/lib endif INCDIR := $(PREFIX)/include/rem CFLAGS += -I$(LIBRE_INC) -Iinclude # XXX ifneq ($(HAVE_ARMV6),) CFLAGS += -DHAVE_ARMV6=1 endif ifneq ($(HAVE_NEON),) CFLAGS += -DHAVE_NEON=1 endif MODMKS := $(patsubst %,src/%/mod.mk,$(MODULES)) SHARED := librem$(LIB_SUFFIX) STATIC := librem.a include $(MODMKS) OBJS ?= $(patsubst %.c,$(BUILD)/%.o,$(filter %.c,$(SRCS))) OBJS += $(patsubst %.S,$(BUILD)/%.o,$(filter %.S,$(SRCS))) all: $(SHARED) $(STATIC) -include $(OBJS:.o=.d) $(SHARED): $(OBJS) @echo " LD $@" @$(LD) $(LFLAGS) $(SH_LFLAGS) $^ -L$(LIBRE_SO) -lre $(LIBS) -o $@ $(STATIC): $(OBJS) @echo " AR $@" @$(AR) $(AFLAGS) $@ $^ ifneq ($(RANLIB),) @$(RANLIB) $@ endif librem.pc: @echo 'prefix='$(PREFIX) > librem.pc @echo 'exec_prefix=$${prefix}' >> librem.pc @echo 'libdir=$${prefix}/lib' >> librem.pc @echo 'includedir=$${prefix}/include/rem' >> librem.pc @echo '' >> librem.pc @echo 'Name: librem' >> librem.pc @echo 'Description: Audio and video processing media library' \ >> librem.pc @echo 'Version: '$(VERSION) >> librem.pc @echo 'URL: http://creytiv.com/rem.html' >> librem.pc @echo 'Libs: -L$${libdir} -lrem -lre' >> librem.pc @echo 'Cflags: -I$${includedir}' >> librem.pc $(BUILD)/%.o: src/%.c $(BUILD) Makefile $(MK) $(MODMKS) @echo " CC $@" @$(CC) $(CFLAGS) -c $< -o $@ $(DFLAGS) $(BUILD)/%.o: src/%.S $(BUILD) Makefile $(MK) $(MODMKS) @echo " AS $@" @$(CC) $(CFLAGS) -c $< -o $@ $(DFLAGS) $(BUILD): Makefile $(MK) $(MODMKS) @mkdir -p $(patsubst %,$(BUILD)/%,$(sort $(dir $(SRCS)))) @touch $@ .PHONY: clean clean: @rm -rf $(SHARED) $(STATIC) librem.pc test.d test.o test $(BUILD) install: $(SHARED) $(STATIC) librem.pc @mkdir -p $(DESTDIR)$(LIBDIR) $(DESTDIR)$(LIBDIR)/pkgconfig \ $(DESTDIR)$(INCDIR) $(INSTALL) -m 0644 $(shell find include -name "*.h") \ $(DESTDIR)$(INCDIR) $(INSTALL) -m 0755 $(SHARED) $(DESTDIR)$(LIBDIR) $(INSTALL) -m 0755 $(STATIC) $(DESTDIR)$(LIBDIR) $(INSTALL) -m 0644 librem.pc $(DESTDIR)$(LIBDIR)/pkgconfig .PHONY: uninstall uninstall: @rm -rf $(DESTDIR)$(INCDIR) @rm -f $(DESTDIR)$(LIBDIR)/$(SHARED) @rm -f $(DESTDIR)$(LIBDIR)/$(STATIC) @rm -f $(DESTDIR)$(LIBDIR)/pkgconfig/librem.pc -include test.d test.o: test.c @echo " CC $@" @$(CC) $(CFLAGS) -c $< -o $@ $(DFLAGS) test$(BIN_SUFFIX): test.o $(SHARED) $(STATIC) @echo " LD $@" @$(LD) $(LFLAGS) $< -L. -lrem -lre $(LIBS) -o $@ rem-0.4.7/src/0000755000175100017510000000000012640750470013663 5ustar rkrishnanrkrishnanrem-0.4.7/src/auconv/0000755000175100017510000000000012640750470015156 5ustar rkrishnanrkrishnanrem-0.4.7/src/auconv/auconv.c0000644000175100017510000000351612631242053016613 0ustar rkrishnanrkrishnan/** * @file auconv.c Audio sample format converter * * Copyright (C) 2010 Creytiv.com */ #include #include #include #include static inline float ausamp_short2float(int16_t in) { float out; out = (float) (in / (1.0 * 0x8000)); return out; } static inline int16_t ausamp_float2short(float in) { double value; int16_t out; value = in * (8.0 * 0x10000000); if (value >= (1.0 * 0x7fffffff)) { out = 32767; } else if (value <= (-8.0 * 0x10000000)) { out = -32768; } else out = (short) (lrint (value) >> 16); return out; } void auconv_from_s16(enum aufmt dst_fmt, void *dst_sampv, const int16_t *src_sampv, size_t sampc) { float *f; uint8_t *b; size_t i; if (!dst_sampv || !src_sampv || !sampc) return; switch (dst_fmt) { case AUFMT_FLOAT: f = dst_sampv; for (i=0; i> 8; b[3*i+1] = s & 0xff; b[3*i+0] = 0; } break; default: (void)re_fprintf(stderr, "auconv: sample format %d (%s)" " not supported\n", dst_fmt, aufmt_name(dst_fmt)); return; } } void auconv_to_s16(int16_t *dst_sampv, enum aufmt src_fmt, void *src_sampv, size_t sampc) { float *f; uint8_t *b; size_t i; if (!dst_sampv || !src_sampv || !sampc) return; switch (src_fmt) { case AUFMT_FLOAT: f = src_sampv; for (i=0; i #include #include #include #define SCALE (32767) #define DTMF_AMP (5) #if !defined (M_PI) #define M_PI 3.14159265358979323846264338327 #endif static inline uint32_t digit2lo(int digit) { switch (digit) { case '1': case '2': case '3': case 'A': return 697; case '4': case '5': case '6': case 'B': return 770; case '7': case '8': case '9': case 'C': return 852; case '*': case '0': case '#': case 'D': return 941; default: return 0; } } static inline uint32_t digit2hi(int digit) { switch (digit) { case '1': case '4': case '7': case '*': return 1209; case '2': case '5': case '8': case '0': return 1336; case '3': case '6': case '9': case '#': return 1477; case 'A': case 'B': case 'C': case 'D': return 1633; default: return 0; } } /** * Generate a dual-tone sine wave into a PCM buffer * * @param mb Buffer for PCM samples * @param srate Sample rate in [Hz] * @param f1 Frequency number one * @param l1 Level of f1 from 0-100 * @param f2 Frequency number two * @param l2 Level of f2 from 0-100 * * @return 0 for success, otherwise error code */ int autone_sine(struct mbuf *mb, uint32_t srate, uint32_t f1, int l1, uint32_t f2, int l2) { double d1, d2; uint32_t i; int err = 0; if (!mb || !srate) return EINVAL; d1 = 1.0f * f1 / srate; d2 = 1.0f * f2 / srate; for (i=0; i #include const uint8_t g711_l2u[4096] = { 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8, 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0, 0xef, 0xef, 0xee, 0xee, 0xed, 0xed, 0xec, 0xec, 0xeb, 0xeb, 0xea, 0xea, 0xe9, 0xe9, 0xe8, 0xe8, 0xe7, 0xe7, 0xe6, 0xe6, 0xe5, 0xe5, 0xe4, 0xe4, 0xe3, 0xe3, 0xe2, 0xe2, 0xe1, 0xe1, 0xe0, 0xe0, 0xdf, 0xdf, 0xdf, 0xdf, 0xde, 0xde, 0xde, 0xde, 0xdd, 0xdd, 0xdd, 0xdd, 0xdc, 0xdc, 0xdc, 0xdc, 0xdb, 0xdb, 0xdb, 0xdb, 0xda, 0xda, 0xda, 0xda, 0xd9, 0xd9, 0xd9, 0xd9, 0xd8, 0xd8, 0xd8, 0xd8, 0xd7, 0xd7, 0xd7, 0xd7, 0xd6, 0xd6, 0xd6, 0xd6, 0xd5, 0xd5, 0xd5, 0xd5, 0xd4, 0xd4, 0xd4, 0xd4, 0xd3, 0xd3, 0xd3, 0xd3, 0xd2, 0xd2, 0xd2, 0xd2, 0xd1, 0xd1, 0xd1, 0xd1, 0xd0, 0xd0, 0xd0, 0xd0, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xce, 0xce, 0xce, 0xce, 0xce, 0xce, 0xce, 0xce, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcb, 0xcb, 0xcb, 0xcb, 0xcb, 0xcb, 0xcb, 0xcb, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xc9, 0xc9, 0xc9, 0xc9, 0xc9, 0xc9, 0xc9, 0xc9, 0xc8, 0xc8, 0xc8, 0xc8, 0xc8, 0xc8, 0xc8, 0xc8, 0xc7, 0xc7, 0xc7, 0xc7, 0xc7, 0xc7, 0xc7, 0xc7, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, }; const uint8_t g711_l2A[2048] = { 0xd5, 0xd4, 0xd7, 0xd6, 0xd1, 0xd0, 0xd3, 0xd2, 0xdd, 0xdc, 0xdf, 0xde, 0xd9, 0xd8, 0xdb, 0xda, 0xc5, 0xc4, 0xc7, 0xc6, 0xc1, 0xc0, 0xc3, 0xc2, 0xcd, 0xcc, 0xcf, 0xce, 0xc9, 0xc8, 0xcb, 0xca, 0xf5, 0xf5, 0xf4, 0xf4, 0xf7, 0xf7, 0xf6, 0xf6, 0xf1, 0xf1, 0xf0, 0xf0, 0xf3, 0xf3, 0xf2, 0xf2, 0xfd, 0xfd, 0xfc, 0xfc, 0xff, 0xff, 0xfe, 0xfe, 0xf9, 0xf9, 0xf8, 0xf8, 0xfb, 0xfb, 0xfa, 0xfa, 0xe5, 0xe5, 0xe5, 0xe5, 0xe4, 0xe4, 0xe4, 0xe4, 0xe7, 0xe7, 0xe7, 0xe7, 0xe6, 0xe6, 0xe6, 0xe6, 0xe1, 0xe1, 0xe1, 0xe1, 0xe0, 0xe0, 0xe0, 0xe0, 0xe3, 0xe3, 0xe3, 0xe3, 0xe2, 0xe2, 0xe2, 0xe2, 0xed, 0xed, 0xed, 0xed, 0xec, 0xec, 0xec, 0xec, 0xef, 0xef, 0xef, 0xef, 0xee, 0xee, 0xee, 0xee, 0xe9, 0xe9, 0xe9, 0xe9, 0xe8, 0xe8, 0xe8, 0xe8, 0xeb, 0xeb, 0xeb, 0xeb, 0xea, 0xea, 0xea, 0xea, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, }; const int16_t g711_u2l[256] = { -32124,-31100,-30076,-29052,-28028,-27004,-25980,-24956, -23932,-22908,-21884,-20860,-19836,-18812,-17788,-16764, -15996,-15484,-14972,-14460,-13948,-13436,-12924,-12412, -11900,-11388,-10876,-10364, -9852, -9340, -8828, -8316, -7932, -7676, -7420, -7164, -6908, -6652, -6396, -6140, -5884, -5628, -5372, -5116, -4860, -4604, -4348, -4092, -3900, -3772, -3644, -3516, -3388, -3260, -3132, -3004, -2876, -2748, -2620, -2492, -2364, -2236, -2108, -1980, -1884, -1820, -1756, -1692, -1628, -1564, -1500, -1436, -1372, -1308, -1244, -1180, -1116, -1052, -988, -924, -876, -844, -812, -780, -748, -716, -684, -652, -620, -588, -556, -524, -492, -460, -428, -396, -372, -356, -340, -324, -308, -292, -276, -260, -244, -228, -212, -196, -180, -164, -148, -132, -120, -112, -104, -96, -88, -80, -72, -64, -56, -48, -40, -32, -24, -16, -8, -2, 32124, 31100, 30076, 29052, 28028, 27004, 25980, 24956, 23932, 22908, 21884, 20860, 19836, 18812, 17788, 16764, 15996, 15484, 14972, 14460, 13948, 13436, 12924, 12412, 11900, 11388, 10876, 10364, 9852, 9340, 8828, 8316, 7932, 7676, 7420, 7164, 6908, 6652, 6396, 6140, 5884, 5628, 5372, 5116, 4860, 4604, 4348, 4092, 3900, 3772, 3644, 3516, 3388, 3260, 3132, 3004, 2876, 2748, 2620, 2492, 2364, 2236, 2108, 1980, 1884, 1820, 1756, 1692, 1628, 1564, 1500, 1436, 1372, 1308, 1244, 1180, 1116, 1052, 988, 924, 876, 844, 812, 780, 748, 716, 684, 652, 620, 588, 556, 524, 492, 460, 428, 396, 372, 356, 340, 324, 308, 292, 276, 260, 244, 228, 212, 196, 180, 164, 148, 132, 120, 112, 104, 96, 88, 80, 72, 64, 56, 48, 40, 32, 24, 16, 8, 2, }; const int16_t g711_A2l[256] = { -5504, -5248, -6016, -5760, -4480, -4224, -4992, -4736, -7552, -7296, -8064, -7808, -6528, -6272, -7040, -6784, -2752, -2624, -3008, -2880, -2240, -2112, -2496, -2368, -3776, -3648, -4032, -3904, -3264, -3136, -3520, -3392, -22016,-20992,-24064,-23040,-17920,-16896,-19968,-18944, -30208,-29184,-32256,-31232,-26112,-25088,-28160,-27136, -11008,-10496,-12032,-11520, -8960, -8448, -9984, -9472, -15104,-14592,-16128,-15616,-13056,-12544,-14080,-13568, -344, -328, -376, -360, -280, -264, -312, -296, -472, -456, -504, -488, -408, -392, -440, -424, -88, -72, -120, -104, -24, -8, -56, -40, -216, -200, -248, -232, -152, -136, -184, -168, -1376, -1312, -1504, -1440, -1120, -1056, -1248, -1184, -1888, -1824, -2016, -1952, -1632, -1568, -1760, -1696, -688, -656, -752, -720, -560, -528, -624, -592, -944, -912, -1008, -976, -816, -784, -880, -848, 5504, 5248, 6016, 5760, 4480, 4224, 4992, 4736, 7552, 7296, 8064, 7808, 6528, 6272, 7040, 6784, 2752, 2624, 3008, 2880, 2240, 2112, 2496, 2368, 3776, 3648, 4032, 3904, 3264, 3136, 3520, 3392, 22016, 20992, 24064, 23040, 17920, 16896, 19968, 18944, 30208, 29184, 32256, 31232, 26112, 25088, 28160, 27136, 11008, 10496, 12032, 11520, 8960, 8448, 9984, 9472, 15104, 14592, 16128, 15616, 13056, 12544, 14080, 13568, 344, 328, 376, 360, 280, 264, 312, 296, 472, 456, 504, 488, 408, 392, 440, 424, 88, 72, 120, 104, 24, 8, 56, 40, 216, 200, 248, 232, 152, 136, 184, 168, 1376, 1312, 1504, 1440, 1120, 1056, 1248, 1184, 1888, 1824, 2016, 1952, 1632, 1568, 1760, 1696, 688, 656, 752, 720, 560, 528, 624, 592, 944, 912, 1008, 976, 816, 784, 880, 848, }; rem-0.4.7/src/fir/0000755000175100017510000000000012640750470014443 5ustar rkrishnanrkrishnanrem-0.4.7/src/fir/fir.c0000644000175100017510000000241312252070337015363 0ustar rkrishnanrkrishnan/** * @file fir.c FIR -- Finite Impulse Response * * Copyright (C) 2010 Creytiv.com */ #include #include #include /** * Reset the FIR-filter * * @param fir FIR-filter state */ void fir_reset(struct fir *fir) { if (!fir) return; memset(fir, 0, sizeof(*fir)); } /** * Process samples with the FIR filter * * @note product of channel and tap-count must be power of two * * @param fir FIR filter * @param outv Output samples * @param inv Input samples * @param inc Number of samples * @param ch Number of channels * @param tapv Filter taps * @param tapc Number of taps */ void fir_filter(struct fir *fir, int16_t *outv, const int16_t *inv, size_t inc, unsigned ch, const int16_t *tapv, size_t tapc) { const unsigned hmask = (ch * (unsigned)tapc) - 1; if (!fir || !outv || !inv || !ch || !tapv || !tapc) return; if (hmask >= ARRAY_SIZE(fir->history) || hmask & (hmask+1)) return; while (inc--) { int64_t acc = 0; unsigned i, j; fir->history[fir->index & hmask] = *inv++; for (i=0, j=fir->index++; ihistory[j & hmask] * tapv[i]; if (acc > 0x3fffffff) acc = 0x3fffffff; else if (acc < -0x40000000) acc = -0x40000000; *outv++ = (int16_t)(acc>>15); } } rem-0.4.7/src/fir/mod.mk0000644000175100017510000000010311552061765015550 0ustar rkrishnanrkrishnan# # mod.mk # # Copyright (C) 2011 Creytiv.com # SRCS += fir/fir.c rem-0.4.7/src/vidmix/0000755000175100017510000000000012640750470015163 5ustar rkrishnanrkrishnanrem-0.4.7/src/vidmix/vidmix.c0000644000175100017510000003147012634536643016643 0ustar rkrishnanrkrishnan/** * @file vidmix.c Video Mixer * * Copyright (C) 2010 Creytiv.com */ #define _BSD_SOURCE 1 #define _DEFAULT_SOURCE 1 #include #define __USE_UNIX98 1 #include #include #include #include #include #include struct vidmix { pthread_rwlock_t rwlock; struct list srcl; bool initialized; }; struct vidmix_source { struct le le; pthread_t thread; pthread_mutex_t mutex; struct vidframe *frame_tx; struct vidframe *frame_rx; struct vidmix *mix; vidmix_frame_h *fh; void *arg; void *focus; bool content_hide; bool focus_full; unsigned fint; bool selfview; bool content; bool clear; bool run; }; static inline void source_mix_full(struct vidframe *mframe, const struct vidframe *frame_src); static inline void clear_frame(struct vidframe *vf) { vidframe_fill(vf, 0, 0, 0); } static void clear_all(struct vidmix *mix) { struct le *le; for (le=mix->srcl.head; le; le=le->next) { struct vidmix_source *src = le->data; src->clear = true; } } static void destructor(void *arg) { struct vidmix *mix = arg; if (mix->initialized) (void)pthread_rwlock_destroy(&mix->rwlock); } static void source_destructor(void *arg) { struct vidmix_source *src = arg; if (src->run) { src->run = false; pthread_join(src->thread, NULL); } if (src->le.list) { pthread_rwlock_wrlock(&src->mix->rwlock); list_unlink(&src->le); clear_all(src->mix); pthread_rwlock_unlock(&src->mix->rwlock); } mem_deref(src->frame_tx); mem_deref(src->frame_rx); mem_deref(src->mix); } static inline void source_mix(struct vidframe *mframe, const struct vidframe *frame_src, unsigned n, unsigned rows, unsigned idx, bool focus, bool focus_this, bool focus_full) { struct vidrect rect; if (!frame_src) return; if (focus) { const unsigned nmin = focus_full ? 12 : 6; n = max((n+1), nmin)/2; if (focus_this) { rect.w = mframe->size.w * (n-1) / n; rect.h = mframe->size.h * (n-1) / n; rect.x = 0; rect.y = 0; } else { rect.w = mframe->size.w / n; rect.h = mframe->size.h / n; if (idx < n) { rect.x = mframe->size.w - rect.w; rect.y = rect.h * idx; } else if (idx < (n*2 - 1)) { rect.x = rect.w * (n*2 - 2 - idx); rect.y = mframe->size.h - rect.h; } else { return; } } } else if (rows == 1) { source_mix_full(mframe, frame_src); return; } else { rect.w = mframe->size.w / rows; rect.h = mframe->size.h / rows; rect.x = rect.w * (idx % rows); rect.y = rect.h * (idx / rows); } vidconv_aspect(mframe, frame_src, &rect); } static inline void source_mix_full(struct vidframe *mframe, const struct vidframe *frame_src) { if (!frame_src) return; if (vidsz_cmp(&mframe->size, &frame_src->size)) { vidframe_copy(mframe, frame_src); } else { struct vidrect rect; rect.w = mframe->size.w; rect.h = mframe->size.h; rect.x = 0; rect.y = 0; vidconv_aspect(mframe, frame_src, &rect); } } static inline unsigned calc_rows(unsigned n) { unsigned rows; for (rows=1;; rows++) if (n <= (rows * rows)) return rows; } static void *vidmix_thread(void *arg) { struct vidmix_source *src = arg; struct vidmix *mix = src->mix; uint64_t ts = tmr_jiffies(); pthread_mutex_lock(&src->mutex); while (src->run) { unsigned n, rows, idx; struct le *le; uint64_t now; pthread_mutex_unlock(&src->mutex); (void)usleep(4000); pthread_mutex_lock(&src->mutex); now = tmr_jiffies(); if (ts > now) continue; if (!src->frame_tx) { ts += src->fint; continue; } pthread_rwlock_rdlock(&mix->rwlock); if (src->clear) { clear_frame(src->frame_tx); src->clear = false; } for (le=mix->srcl.head, n=0; le; le=le->next) { const struct vidmix_source *lsrc = le->data; if (lsrc == src && !src->selfview) continue; if (lsrc->content && src->content_hide) continue; if (lsrc == src->focus && src->focus_full) source_mix_full(src->frame_tx, lsrc->frame_rx); ++n; } rows = calc_rows(n); for (le=mix->srcl.head, idx=0; le; le=le->next) { const struct vidmix_source *lsrc = le->data; if (lsrc == src && !src->selfview) continue; if (lsrc->content && src->content_hide) continue; if (lsrc == src->focus && src->focus_full) continue; source_mix(src->frame_tx, lsrc->frame_rx, n, rows, idx, src->focus != NULL, src->focus == lsrc, src->focus_full); if (src->focus != lsrc) ++idx; } pthread_rwlock_unlock(&mix->rwlock); src->fh((uint32_t)ts * 90, src->frame_tx, src->arg); ts += src->fint; } pthread_mutex_unlock(&src->mutex); return NULL; } static void *content_thread(void *arg) { struct vidmix_source *src = arg; struct vidmix *mix = src->mix; uint64_t ts = tmr_jiffies(); pthread_mutex_lock(&src->mutex); while (src->run) { struct le *le; uint64_t now; pthread_mutex_unlock(&src->mutex); (void)usleep(4000); pthread_mutex_lock(&src->mutex); now = tmr_jiffies(); if (ts > now) continue; pthread_rwlock_rdlock(&mix->rwlock); for (le=mix->srcl.head; le; le=le->next) { const struct vidmix_source *lsrc = le->data; if (!lsrc->content || !lsrc->frame_rx || lsrc == src) continue; src->fh((uint32_t)ts * 90, lsrc->frame_rx, src->arg); break; } pthread_rwlock_unlock(&mix->rwlock); ts += src->fint; } pthread_mutex_unlock(&src->mutex); return NULL; } /** * Allocate a new Video mixer * * @param mixp Pointer to allocated video mixer * * @return 0 for success, otherwise error code */ int vidmix_alloc(struct vidmix **mixp) { pthread_rwlockattr_t attr; struct vidmix *mix; int err; if (!mixp) return EINVAL; mix = mem_zalloc(sizeof(*mix), destructor); if (!mix) return ENOMEM; err = pthread_rwlockattr_init(&attr); if (err) { mem_deref(mix); return err; } #if defined(LINUX) && defined(__GLIBC__) err = pthread_rwlockattr_setkind_np(&attr, PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP); if (err) goto out; #endif err = pthread_rwlock_init(&mix->rwlock, &attr); if (err) goto out; mix->initialized = true; out: (void)pthread_rwlockattr_destroy(&attr); if (err) mem_deref(mix); else *mixp = mix; return err; } /** * Allocate a video mixer source * * @param srcp Pointer to allocated video source * @param mix Video mixer * @param sz Size of output video frame (optional) * @param fps Output frame rate (frames per second) * @param content True if source is of type content * @param fh Mixer frame handler * @param arg Handler argument * * @return 0 for success, otherwise error code */ int vidmix_source_alloc(struct vidmix_source **srcp, struct vidmix *mix, const struct vidsz *sz, unsigned fps, bool content, vidmix_frame_h *fh, void *arg) { struct vidmix_source *src; int err; if (!srcp || !mix || !fps || !fh) return EINVAL; src = mem_zalloc(sizeof(*src), source_destructor); if (!src) return ENOMEM; src->mix = mem_ref(mix); src->fint = 1000/fps; src->content = content; src->fh = fh; src->arg = arg; err = pthread_mutex_init(&src->mutex, NULL); if (err) goto out; if (sz) { err = vidframe_alloc(&src->frame_tx, VID_FMT_YUV420P, sz); if (err) goto out; clear_frame(src->frame_tx); } out: if (err) mem_deref(src); else *srcp = src; return err; } /** * Check if vidmix source is enabled * * @param src Video mixer source * * @return true if enabled, otherwise false */ bool vidmix_source_isenabled(const struct vidmix_source *src) { return src ? (src->le.list != NULL) : false; } /** * Check if vidmix source is running * * @param src Video mixer source * * @return true if running, otherwise false */ bool vidmix_source_isrunning(const struct vidmix_source *src) { return src ? src->run : false; } /** * Get focus source * * @param src Video mixer source * * @return pointer of focused source or NULL if focus is not set */ void *vidmix_source_get_focus(const struct vidmix_source *src) { return src ? src->focus : NULL; } /** * Enable/disable vidmix source * * @param src Video mixer source * @param enable True to enable, false to disable */ void vidmix_source_enable(struct vidmix_source *src, bool enable) { if (!src) return; if (src->le.list && enable) return; if (!src->le.list && !enable) return; pthread_rwlock_wrlock(&src->mix->rwlock); if (enable) { if (src->frame_rx) clear_frame(src->frame_rx); list_append(&src->mix->srcl, &src->le, src); } else { list_unlink(&src->le); } clear_all(src->mix); pthread_rwlock_unlock(&src->mix->rwlock); } /** * Start vidmix source thread * * @param src Video mixer source * * @return 0 for success, otherwise error code */ int vidmix_source_start(struct vidmix_source *src) { int err; if (!src) return EINVAL; if (src->run) return EALREADY; src->run = true; err = pthread_create(&src->thread, NULL, src->content ? content_thread : vidmix_thread, src); if (err) { src->run = false; } return err; } /** * Stop vidmix source thread * * @param src Video mixer source */ void vidmix_source_stop(struct vidmix_source *src) { if (!src) return; if (src->run) { src->run = false; pthread_join(src->thread, NULL); } } /** * Set video mixer output frame size * * @param src Video mixer source * @param sz Size of output video frame * * @return 0 for success, otherwise error code */ int vidmix_source_set_size(struct vidmix_source *src, const struct vidsz *sz) { struct vidframe *frame; int err; if (!src || !sz) return EINVAL; if (src->frame_tx && vidsz_cmp(&src->frame_tx->size, sz)) return 0; err = vidframe_alloc(&frame, VID_FMT_YUV420P, sz); if (err) return err; clear_frame(frame); pthread_mutex_lock(&src->mutex); mem_deref(src->frame_tx); src->frame_tx = frame; pthread_mutex_unlock(&src->mutex); return 0; } /** * Set video mixer output frame rate * * @param src Video mixer source * @param fps Output frame rate (frames per second) */ void vidmix_source_set_rate(struct vidmix_source *src, unsigned fps) { if (!src || !fps) return; pthread_mutex_lock(&src->mutex); src->fint = 1000/fps; pthread_mutex_unlock(&src->mutex); } /** * Set video mixer content hide * * @param src Video mixer source * @param hide True to hide content, false to show */ void vidmix_source_set_content_hide(struct vidmix_source *src, bool hide) { if (!src) return; pthread_mutex_lock(&src->mutex); src->content_hide = hide; src->clear = true; pthread_mutex_unlock(&src->mutex); } /** * Toggle vidmix source selfview * * @param src Video mixer source */ void vidmix_source_toggle_selfview(struct vidmix_source *src) { if (!src) return; pthread_mutex_lock(&src->mutex); src->selfview = !src->selfview; src->clear = true; pthread_mutex_unlock(&src->mutex); } /** * Set focus on selected participant source * * @param src Video mixer source * @param focus_src Video mixer source to focus, NULL to clear focus state * @param focus_full Full focus */ void vidmix_source_set_focus(struct vidmix_source *src, const struct vidmix_source *focus_src, bool focus_full) { if (!src) return; pthread_mutex_lock(&src->mutex); src->focus_full = focus_full; src->focus = (void *)focus_src; src->clear = true; pthread_mutex_unlock(&src->mutex); } /** * Set focus on selected participant * * @param src Video mixer source * @param pidx Participant to focus, 0 to disable */ void vidmix_source_set_focus_idx(struct vidmix_source *src, unsigned pidx) { bool focus_full = false; void *focus = NULL; if (!src) return; if (pidx > 0) { struct le *le; unsigned i; pthread_rwlock_rdlock(&src->mix->rwlock); for (le=src->mix->srcl.head, i=1; le; le=le->next) { const struct vidmix_source *lsrc = le->data; if (lsrc == src && !src->selfview) continue; if (lsrc->content && src->content_hide) continue; if (i++ == pidx) { focus = (void *)lsrc; break; } } pthread_rwlock_unlock(&src->mix->rwlock); } if (focus && focus == src->focus) focus_full = !src->focus_full; pthread_mutex_lock(&src->mutex); src->focus_full = focus_full; src->focus = focus; src->clear = true; pthread_mutex_unlock(&src->mutex); } /** * Put a video frame into the video mixer * * @param src Video source * @param frame Video frame */ void vidmix_source_put(struct vidmix_source *src, const struct vidframe *frame) { if (!src || !frame || frame->fmt != VID_FMT_YUV420P) return; if (!src->frame_rx || !vidsz_cmp(&src->frame_rx->size, &frame->size)) { struct vidframe *frm; int err; err = vidframe_alloc(&frm, VID_FMT_YUV420P, &frame->size); if (err) return; pthread_rwlock_wrlock(&src->mix->rwlock); mem_deref(src->frame_rx); src->frame_rx = frm; clear_all(src->mix); pthread_rwlock_unlock(&src->mix->rwlock); } vidframe_copy(src->frame_rx, frame); } rem-0.4.7/src/vidmix/mod.mk0000644000175100017510000000011111547711207016264 0ustar rkrishnanrkrishnan# # mod.mk # # Copyright (C) 2010 Creytiv.com # SRCS += vidmix/vidmix.c rem-0.4.7/src/aubuf/0000755000175100017510000000000012640750470014765 5ustar rkrishnanrkrishnanrem-0.4.7/src/aubuf/aubuf.c0000644000175100017510000001264411761476364016254 0ustar rkrishnanrkrishnan/** * @file aubuf.c Audio Buffer * * Copyright (C) 2010 Creytiv.com */ #include #include #include #define AUBUF_DEBUG 0 /** Locked audio-buffer with almost zero-copy */ struct aubuf { struct list afl; struct lock *lock; size_t wish_sz; size_t cur_sz; size_t max_sz; bool filling; uint64_t ts; #if AUBUF_DEBUG struct { size_t or; size_t ur; } stats; #endif }; struct auframe { struct le le; struct mbuf *mb; }; static void auframe_destructor(void *arg) { struct auframe *af = arg; list_unlink(&af->le); mem_deref(af->mb); } static void aubuf_destructor(void *arg) { struct aubuf *ab = arg; list_flush(&ab->afl); mem_deref(ab->lock); } /** * Allocate a new audio buffer * * @param abp Pointer to allocated audio buffer * @param min_sz Minimum buffer size * @param max_sz Maximum buffer size (0 for no max size) * * @return 0 for success, otherwise error code */ int aubuf_alloc(struct aubuf **abp, size_t min_sz, size_t max_sz) { struct aubuf *ab; int err; if (!abp || !min_sz) return EINVAL; ab = mem_zalloc(sizeof(*ab), aubuf_destructor); if (!ab) return ENOMEM; err = lock_alloc(&ab->lock); if (err) goto out; ab->wish_sz = min_sz; ab->max_sz = max_sz; ab->filling = true; out: if (err) mem_deref(ab); else *abp = ab; return err; } /** * Append a PCM-buffer to the end of the audio buffer * * @param ab Audio buffer * @param mb Mbuffer with PCM samples * * @return 0 for success, otherwise error code */ int aubuf_append(struct aubuf *ab, struct mbuf *mb) { struct auframe *af; if (!ab || !mb) return EINVAL; af = mem_zalloc(sizeof(*af), auframe_destructor); if (!af) return ENOMEM; af->mb = mem_ref(mb); lock_write_get(ab->lock); list_append(&ab->afl, &af->le, af); ab->cur_sz += mbuf_get_left(mb); if (ab->max_sz && ab->cur_sz > ab->max_sz) { #if AUBUF_DEBUG ++ab->stats.or; (void)re_printf("aubuf: %p overrun (cur=%zu)\n", ab, ab->cur_sz); #endif af = list_ledata(ab->afl.head); if (af) { ab->cur_sz -= mbuf_get_left(af->mb); mem_deref(af); } } lock_rel(ab->lock); return 0; } /** * Write PCM samples to the audio buffer * * @param ab Audio buffer * @param p Pointer to PCM data * @param sz Number of bytes to write * * @return 0 for success, otherwise error code */ int aubuf_write(struct aubuf *ab, const uint8_t *p, size_t sz) { struct mbuf *mb = mbuf_alloc(sz); int err; if (!mb) return ENOMEM; (void)mbuf_write_mem(mb, p, sz); mb->pos = 0; err = aubuf_append(ab, mb); mem_deref(mb); return err; } /** * Read PCM samples from the audio buffer. If there is not enough data * in the audio buffer, silence will be read. * * @param ab Audio buffer * @param p Buffer where PCM samples are read into * @param sz Number of bytes to read */ void aubuf_read(struct aubuf *ab, uint8_t *p, size_t sz) { struct le *le; if (!ab || !p || !sz) return; lock_write_get(ab->lock); if (ab->cur_sz < (ab->filling ? ab->wish_sz : sz)) { #if AUBUF_DEBUG if (!ab->filling) { ++ab->stats.ur; (void)re_printf("aubuf: %p underrun (cur=%zu)\n", ab, ab->cur_sz); } #endif ab->filling = true; memset(p, 0, sz); goto out; } ab->filling = false; le = ab->afl.head; while (le) { struct auframe *af = le->data; size_t n; le = le->next; n = min(mbuf_get_left(af->mb), sz); (void)mbuf_read_mem(af->mb, p, n); ab->cur_sz -= n; if (!mbuf_get_left(af->mb)) mem_deref(af); if (n == sz) break; p += n; sz -= n; } out: lock_rel(ab->lock); } /** * Timed read PCM samples from the audio buffer. If there is not enough data * in the audio buffer, silence will be read. * * @param ab Audio buffer * @param ptime Packet time in [ms] * @param p Buffer where PCM samples are read into * @param sz Number of bytes to read * * @note This does the same as aubuf_read() except that it also takes * timing into consideration. * * @return 0 if valid PCM was read, ETIMEDOUT if no PCM is ready yet */ int aubuf_get(struct aubuf *ab, uint32_t ptime, uint8_t *p, size_t sz) { uint64_t now; int err = 0; if (!ab || !ptime) return EINVAL; lock_write_get(ab->lock); now = tmr_jiffies(); if (!ab->ts) ab->ts = now; if (now < ab->ts) { err = ETIMEDOUT; goto out; } ab->ts += ptime; out: lock_rel(ab->lock); if (!err) aubuf_read(ab, p, sz); return err; } /** * Flush the audio buffer * * @param ab Audio buffer */ void aubuf_flush(struct aubuf *ab) { if (!ab) return; lock_write_get(ab->lock); list_flush(&ab->afl); ab->filling = true; ab->cur_sz = 0; ab->ts = 0; lock_rel(ab->lock); } /** * Audio buffer debug handler, use with fmt %H * * @param pf Print function * @param ab Audio buffer * * @return 0 if success, otherwise errorcode */ int aubuf_debug(struct re_printf *pf, const struct aubuf *ab) { int err; if (!ab) return 0; lock_read_get(ab->lock); err = re_hprintf(pf, "wish_sz=%zu cur_sz=%zu filling=%d", ab->wish_sz, ab->cur_sz, ab->filling); #if AUBUF_DEBUG err |= re_hprintf(pf, " [overrun=%zu underrun=%zu]", ab->stats.or, ab->stats.ur); #endif lock_rel(ab->lock); return err; } /** * Get the current number of bytes in the audio buffer * * @param ab Audio buffer * * @return Number of bytes in the audio buffer */ size_t aubuf_cur_size(const struct aubuf *ab) { size_t sz; if (!ab) return 0; lock_read_get(ab->lock); sz = ab->cur_sz; lock_rel(ab->lock); return sz; } rem-0.4.7/src/aubuf/mod.mk0000644000175100017510000000010711547711207016073 0ustar rkrishnanrkrishnan# # mod.mk # # Copyright (C) 2010 Creytiv.com # SRCS += aubuf/aubuf.c rem-0.4.7/src/auresamp/0000755000175100017510000000000012640750470015500 5ustar rkrishnanrkrishnanrem-0.4.7/src/auresamp/mod.mk0000644000175100017510000000011311552061765016606 0ustar rkrishnanrkrishnan# # mod.mk # # Copyright (C) 2010 Creytiv.com # SRCS += auresamp/resamp.c rem-0.4.7/src/auresamp/resamp.c0000644000175100017510000001350412252070337017132 0ustar rkrishnanrkrishnan/** * @file resamp.c Audio Resampler * * Copyright (C) 2010 Creytiv.com */ #include #include #include #include /* 48kHz sample-rate, 4kHz cutoff (pass 0-3kHz, stop 5-24kHz) */ static const int16_t fir_48_4[] = { 62, -176, -329, -556, -802, -1005, -1090, -985, -636, -23, 826, 1837, 2894, 3859, 4595, 4994, 4994, 4595, 3859, 2894, 1837, 826, -23, -636, -985, -1090, -1005, -802, -556, -329, -176, 62 }; /* 48kHz sample-rate, 8kHz cutoff (pass 0-7kHz, stop 9-24kHz) */ static const int16_t fir_48_8[] = { 238, 198, -123, -738, -1268, -1204, -380, 714, 1164, 376, -1220, -2206, -1105, 2395, 6909, 10069, 10069, 6909, 2395, -1105, -2206, -1220, 376, 1164, 714, -380, -1204, -1268, -738, -123, 198, 238 }; static void upsample_mono2mono(int16_t *outv, const int16_t *inv, size_t inc, unsigned ratio) { unsigned i; while (inc >= 1) { for (i=0; i= 1) { for (i=0; i= 2) { const int16_t s = inv[0]/2 + inv[1]/2; for (i=0; i= 2) { for (i=0; i= ratio) { *outv++ = *inv; inv += ratio; inc -= ratio; } } static void downsample_mono2stereo(int16_t *outv, const int16_t *inv, size_t inc, unsigned ratio) { while (inc >= ratio) { *outv++ = *inv; *outv++ = *inv; inv += ratio; inc -= ratio; } } static void downsample_stereo2mono(int16_t *outv, const int16_t *inv, size_t inc, unsigned ratio) { ratio *= 2; while (inc >= ratio) { *outv++ = inv[0]/2 + inv[1]/2; inv += ratio; inc -= ratio; } } static void downsample_stereo2stereo(int16_t *outv, const int16_t *inv, size_t inc, unsigned ratio) { ratio *= 2; while (inc >= ratio) { *outv++ = inv[0]; *outv++ = inv[1]; inv += ratio; inc -= ratio; } } /** * Initialize a resampler object * * @param rs Resampler to initialize */ void auresamp_init(struct auresamp *rs) { if (!rs) return; memset(rs, 0, sizeof(*rs)); fir_reset(&rs->fir); } /** * Configure a resampler object * * @note The sample rate ratio must be an integer * * @param rs Resampler * @param irate Input sample rate * @param ich Input channel count * @param orate Output sample rate * @param och Output channel count * * @return 0 if success, otherwise error code */ int auresamp_setup(struct auresamp *rs, uint32_t irate, unsigned ich, uint32_t orate, unsigned och) { if (!rs || !irate || !ich || !orate || !och) return EINVAL; if (orate == irate && och == ich) { auresamp_init(rs); return 0; } if (orate >= irate) { if (orate % irate) return ENOTSUP; if (ich == 1 && och == 1) rs->resample = upsample_mono2mono; else if (ich == 1 && och == 2) rs->resample = upsample_mono2stereo; else if (ich == 2 && och == 1) rs->resample = upsample_stereo2mono; else if (ich == 2 && och == 2) rs->resample = upsample_stereo2stereo; else return ENOTSUP; if (!rs->up || orate != rs->orate || och != rs->och) fir_reset(&rs->fir); rs->ratio = orate / irate; rs->up = true; if (orate == 48000 && irate == 16000) { rs->tapv = fir_48_8; rs->tapc = ARRAY_SIZE(fir_48_8); } else { rs->tapv = fir_48_4; rs->tapc = ARRAY_SIZE(fir_48_4); } } else { if (irate % orate) return ENOTSUP; if (ich == 1 && och == 1) rs->resample = downsample_mono2mono; else if (ich == 1 && och == 2) rs->resample = downsample_mono2stereo; else if (ich == 2 && och == 1) rs->resample = downsample_stereo2mono; else if (ich == 2 && och == 2) rs->resample = downsample_stereo2stereo; else return ENOTSUP; if (rs->up || irate != rs->irate || ich != rs->ich) fir_reset(&rs->fir); rs->ratio = irate / orate; rs->up = false; if (irate == 48000 && orate == 16000) { rs->tapv = fir_48_8; rs->tapc = ARRAY_SIZE(fir_48_8); } else { rs->tapv = fir_48_4; rs->tapc = ARRAY_SIZE(fir_48_4); } } rs->orate = orate; rs->och = och; rs->irate = irate; rs->ich = ich; return 0; } /** * Resample * * @note When downsampling, the input count must be divisible by rate ratio * * @param rs Resampler * @param outv Output samples * @param outc Output sample count (in/out) * @param inv Input samples * @param inc Input sample count * * @return 0 if success, otherwise error code */ int auresamp(struct auresamp *rs, int16_t *outv, size_t *outc, const int16_t *inv, size_t inc) { size_t incc, outcc; if (!rs || !rs->resample || !outv || !outc || !inv) return EINVAL; incc = inc / rs->ich; if (rs->up) { outcc = incc * rs->ratio; if (*outc < outcc * rs->och) return ENOMEM; rs->resample(outv, inv, inc, rs->ratio); *outc = outcc * rs->och; fir_filter(&rs->fir, outv, outv, *outc, rs->och, rs->tapv, rs->tapc); } else { outcc = incc / rs->ratio; if (*outc < outcc * rs->och || *outc < inc) return ENOMEM; fir_filter(&rs->fir, outv, inv, inc, rs->ich, rs->tapv, rs->tapc); rs->resample(outv, outv, inc, rs->ratio); *outc = outcc * rs->och; } return 0; } rem-0.4.7/src/vidconv/0000755000175100017510000000000012640750470015333 5ustar rkrishnanrkrishnanrem-0.4.7/src/vidconv/mod.mk0000644000175100017510000000011111607604610016430 0ustar rkrishnanrkrishnan# # mod.mk # # Copyright (C) 2010 Creytiv.com # SRCS += vidconv/vconv.c rem-0.4.7/src/vidconv/vconv.c0000644000175100017510000004351312211434137016631 0ustar rkrishnanrkrishnan/** * @file vconv.c Video Conversion * * Copyright (C) 2010 Creytiv.com */ #include #include #include #include #include #if 0 /* * The lookup tables are generated with the following code: */ #define P 14 #define COEF_RV ((int32_t) (1.370705f * (float)(1 << P))) #define COEF_GU ((int32_t) (-0.337633f * (float)(1 << P))) #define COEF_GV ((int32_t) (-0.698001f * (float)(1 << P))) #define COEF_BU ((int32_t) (1.732446f * (float)(1 << P))) #define ERV(a) (COEF_RV * ((a) - 128)) #define EGU(a) (COEF_GU * ((a) - 128)) #define EGV(a) (COEF_GV * ((a) - 128)) #define EBU(a) (COEF_BU * ((a) - 128)) int16_t CRV[256]; int16_t CGU[256]; int16_t CGV[256]; int16_t CBU[256]; static void init_table(void) { int i; for (i = 0; i < 256; ++i) { CRV[i] = ERV(i) >> P; CGU[i] = EGU(i) >> P; CGV[i] = EGV(i) >> P; CBU[i] = EBU(i) >> P; } } #endif static const int16_t CRV[256] = { -176,-175,-173,-172,-170,-169,-168,-166,-165,-164,-162,-161, -159,-158,-157,-155,-154,-153,-151,-150,-149,-147,-146,-144, -143,-142,-140,-139,-138,-136,-135,-133,-132,-131,-129,-128, -127,-125,-124,-122,-121,-120,-118,-117,-116,-114,-113,-112, -110,-109,-107,-106,-105,-103,-102,-101, -99, -98, -96, -95, -94, -92, -91, -90, -88, -87, -85, -84, -83, -81, -80, -79, -77, -76, -75, -73, -72, -70, -69, -68, -66, -65, -64, -62, -61, -59, -58, -57, -55, -54, -53, -51, -50, -48, -47, -46, -44, -43, -42, -40, -39, -38, -36, -35, -33, -32, -31, -29, -28, -27, -25, -24, -22, -21, -20, -18, -17, -16, -14, -13, -11, -10, -9, -7, -6, -5, -3, -2, 0, 1, 2, 4, 5, 6, 8, 9, 10, 12, 13, 15, 16, 17, 19, 20, 21, 23, 24, 26, 27, 28, 30, 31, 32, 34, 35, 37, 38, 39, 41, 42, 43, 45, 46, 47, 49, 50, 52, 53, 54, 56, 57, 58, 60, 61, 63, 64, 65, 67, 68, 69, 71, 72, 74, 75, 76, 78, 79, 80, 82, 83, 84, 86, 87, 89, 90, 91, 93, 94, 95, 97, 98, 100, 101, 102, 104, 105, 106, 108, 109, 111, 112, 113, 115, 116, 117, 119, 120, 121, 123, 124, 126, 127, 128, 130, 131, 132, 134, 135, 137, 138, 139, 141, 142, 143, 145, 146, 148, 149, 150, 152, 153, 154, 156, 157, 158, 160, 161, 163, 164, 165, 167, 168, 169, 171, 172, 174}; static const int16_t CGU[256] = { 43, 42, 42, 42, 41, 41, 41, 40, 40, 40, 39, 39, 39, 38, 38, 38, 37, 37, 37, 36, 36, 36, 35, 35, 35, 34, 34, 34, 33, 33, 33, 32, 32, 32, 31, 31, 31, 30, 30, 30, 29, 29, 29, 28, 28, 28, 27, 27, 27, 26, 26, 25, 25, 25, 24, 24, 24, 23, 23, 23, 22, 22, 22, 21, 21, 21, 20, 20, 20, 19, 19, 19, 18, 18, 18, 17, 17, 17, 16, 16, 16, 15, 15, 15, 14, 14, 14, 13, 13, 13, 12, 12, 12, 11, 11, 11, 10, 10, 10, 9, 9, 9, 8, 8, 8, 7, 7, 7, 6, 6, 6, 5, 5, 5, 4, 4, 4, 3, 3, 3, 2, 2, 2, 1, 1, 1, 0, 0, 0, -1, -1, -2, -2, -2, -3, -3, -3, -4, -4, -4, -5, -5, -5, -6, -6, -6, -7, -7, -7, -8, -8, -8, -9, -9, -9, -10, -10, -10, -11, -11, -11, -12, -12, -12, -13, -13, -13, -14, -14, -14, -15, -15, -15, -16, -16, -16, -17, -17, -17, -18, -18, -18, -19, -19, -19, -20, -20, -20, -21, -21, -21, -22, -22, -22, -23, -23, -23, -24, -24, -24, -25, -25, -25, -26, -26, -26, -27, -27, -28, -28, -28, -29, -29, -29, -30, -30, -30, -31, -31, -31, -32, -32, -32, -33, -33, -33, -34, -34, -34, -35, -35, -35, -36, -36, -36, -37, -37, -37, -38, -38, -38, -39, -39, -39, -40, -40, -40, -41, -41, -41, -42, -42, -42, -43, -43, -43}; static const int16_t CGV[256] = { 89, 88, 87, 87, 86, 85, 85, 84, 83, 83, 82, 81, 80, 80, 79, 78, 78, 77, 76, 76, 75, 74, 73, 73, 72, 71, 71, 70, 69, 69, 68, 67, 67, 66, 65, 64, 64, 63, 62, 62, 61, 60, 60, 59, 58, 57, 57, 56, 55, 55, 54, 53, 53, 52, 51, 50, 50, 49, 48, 48, 47, 46, 46, 45, 44, 43, 43, 42, 41, 41, 40, 39, 39, 38, 37, 36, 36, 35, 34, 34, 33, 32, 32, 31, 30, 30, 29, 28, 27, 27, 26, 25, 25, 24, 23, 23, 22, 21, 20, 20, 19, 18, 18, 17, 16, 16, 15, 14, 13, 13, 12, 11, 11, 10, 9, 9, 8, 7, 6, 6, 5, 4, 4, 3, 2, 2, 1, 0, 0, -1, -2, -3, -3, -4, -5, -5, -6, -7, -7, -8, -9, -10, -10, -11, -12, -12, -13, -14, -14, -15, -16, -17, -17, -18, -19, -19, -20, -21, -21, -22, -23, -24, -24, -25, -26, -26, -27, -28, -28, -29, -30, -31, -31, -32, -33, -33, -34, -35, -35, -36, -37, -37, -38, -39, -40, -40, -41, -42, -42, -43, -44, -44, -45, -46, -47, -47, -48, -49, -49, -50, -51, -51, -52, -53, -54, -54, -55, -56, -56, -57, -58, -58, -59, -60, -61, -61, -62, -63, -63, -64, -65, -65, -66, -67, -68, -68, -69, -70, -70, -71, -72, -72, -73, -74, -74, -75, -76, -77, -77, -78, -79, -79, -80, -81, -81, -82, -83, -84, -84, -85, -86, -86, -87, -88, -88, -89}; static const int16_t CBU[256] = { -222,-221,-219,-217,-215,-214,-212,-210,-208,-207,-205,-203, -201,-200,-198,-196,-195,-193,-191,-189,-188,-186,-184,-182, -181,-179,-177,-175,-174,-172,-170,-169,-167,-165,-163,-162, -160,-158,-156,-155,-153,-151,-149,-148,-146,-144,-143,-141, -139,-137,-136,-134,-132,-130,-129,-127,-125,-124,-122,-120, -118,-117,-115,-113,-111,-110,-108,-106,-104,-103,-101, -99, -98, -96, -94, -92, -91, -89, -87, -85, -84, -82, -80, -78, -77, -75, -73, -72, -70, -68, -66, -65, -63, -61, -59, -58, -56, -54, -52, -51, -49, -47, -46, -44, -42, -40, -39, -37, -35, -33, -32, -30, -28, -26, -25, -23, -21, -20, -18, -16, -14, -13, -11, -9, -7, -6, -4, -2, 0, 1, 3, 5, 6, 8, 10, 12, 13, 15, 17, 19, 20, 22, 24, 25, 27, 29, 31, 32, 34, 36, 38, 39, 41, 43, 45, 46, 48, 50, 51, 53, 55, 57, 58, 60, 62, 64, 65, 67, 69, 71, 72, 74, 76, 77, 79, 81, 83, 84, 86, 88, 90, 91, 93, 95, 97, 98, 100, 102, 103, 105, 107, 109, 110, 112, 114, 116, 117, 119, 121, 123, 124, 126, 128, 129, 131, 133, 135, 136, 138, 140, 142, 143, 145, 147, 148, 150, 152, 154, 155, 157, 159, 161, 162, 164, 166, 168, 169, 171, 173, 174, 176, 178, 180, 181, 183, 185, 187, 188, 190, 192, 194, 195, 197, 199, 200, 202, 204, 206, 207, 209, 211, 213, 214, 216, 218, 220}; static inline void yuv2rgb(uint8_t *rgb, uint8_t y, int ruv, int guv, int buv) { *rgb++ = saturate_u8(y + buv); *rgb++ = saturate_u8(y + guv); *rgb++ = saturate_u8(y + ruv); *rgb = 0; } static inline void yuv2rgb565(uint8_t *rgb, uint8_t y, int ruv, int guv, int buv) { int r = saturate_u8(y + ruv) >> 3; int g = saturate_u8(y + guv) >> 2; int b = saturate_u8(y + buv) >> 3; rgb[1] = r << 3 | g >> 3; rgb[0] = g << 5 | b; } static inline void yuv2rgb555(uint8_t *rgb, uint8_t y, int ruv, int guv, int buv) { uint8_t r = saturate_u8(y + ruv) >> 3; uint8_t g = saturate_u8(y + guv) >> 3; uint8_t b = saturate_u8(y + buv) >> 3; rgb[1] = r << 2 | g >> 3; rgb[0] = g << 5 | b; } typedef void (line_h)(unsigned xoffs, unsigned width, double rw, unsigned yd, unsigned ys, unsigned ys2, uint8_t *dd0, uint8_t *dd1, uint8_t *dd2, unsigned lsd, const uint8_t *sd0, const uint8_t *sd1, const uint8_t *sd2, unsigned lss); static void yuv420p_to_yuv420p(unsigned xoffs, unsigned width, double rw, unsigned yd, unsigned ys, unsigned ys2, uint8_t *dd0, uint8_t *dd1, uint8_t *dd2, unsigned lsd, const uint8_t *ds0, const uint8_t *ds1, const uint8_t *ds2, unsigned lss ) { unsigned x, xd, xs, xs2; unsigned id, is; for (x=0; x>1) + (ys>>1)*lss/2; dd1[id] = ds1[is]; dd2[id] = ds2[is]; } } static void yuyv422_to_yuv420p(unsigned xoffs, unsigned width, double rw, unsigned yd, unsigned ys, unsigned ys2, uint8_t *dd0, uint8_t *dd1, uint8_t *dd2, unsigned lsd, const uint8_t *sd0, const uint8_t *sd1, const uint8_t *sd2, unsigned lss ) { unsigned x, xd, xs; unsigned id, is, is2; (void)sd1; (void)sd2; for (x=0; x> 16, x0 >> 8, x0); dd0[id+1] = rgb2y(x1 >> 16, x1 >> 8, x1); dd0[id + lsd] = rgb2y(x2 >> 16, x2 >> 8, x2); dd0[id+1 + lsd] = rgb2y(x3 >> 16, x3 >> 8, x3); id = xd/2 + yd*lsd/4; dd1[id] = rgb2u(x0 >> 16, x0 >> 8, x0); dd2[id] = rgb2v(x0 >> 16, x0 >> 8, x0); } } static void yuv420p_to_rgb32(unsigned xoffs, unsigned width, double rw, unsigned yd, unsigned ys, unsigned ys2, uint8_t *dd0, uint8_t *dd1, uint8_t *dd2, unsigned lsd, const uint8_t *ds0, const uint8_t *ds1, const uint8_t *ds2, unsigned lss) { unsigned x, xd, xs, xs2; unsigned id, is; (void)dd1; (void)dd2; for (x=0; x>1) + (ys>>1)*lss/2; u = ds1[is]; v = ds2[is]; ruv = CRV[v]; guv = CGV[v] + CGU[u]; buv = CBU[u]; yuv2rgb(&dd0[id], ds0[xs + ys*lss], ruv, guv, buv); yuv2rgb(&dd0[id+4], ds0[xs2 + ys*lss], ruv, guv, buv); yuv2rgb(&dd0[id + lsd], ds0[xs + ys2*lss], ruv, guv, buv); yuv2rgb(&dd0[id+4 + lsd], ds0[xs2 + ys2*lss], ruv, guv, buv); } } static void yuv420p_to_rgb565(unsigned xoffs, unsigned width, double rw, unsigned yd, unsigned ys, unsigned ys2, uint8_t *dd0, uint8_t *dd1, uint8_t *dd2, unsigned lsd, const uint8_t *ds0, const uint8_t *ds1, const uint8_t *ds2, unsigned lss) { unsigned x, xd, xs, xs2; unsigned id, is; (void)dd1; (void)dd2; for (x=0; x>1) + (ys>>1)*lss/2; u = ds1[is]; v = ds2[is]; ruv = CRV[v]; guv = CGV[v] + CGU[u]; buv = CBU[u]; yuv2rgb565(&dd0[id], ds0[xs + ys*lss], ruv, guv,buv); yuv2rgb565(&dd0[id+2], ds0[xs2 + ys*lss], ruv, guv,buv); yuv2rgb565(&dd0[id + lsd], ds0[xs + ys2*lss], ruv, guv,buv); yuv2rgb565(&dd0[id+2 + lsd], ds0[xs2 + ys2*lss], ruv, guv,buv); } } static void yuv420p_to_rgb555(unsigned xoffs, unsigned width, double rw, unsigned yd, unsigned ys, unsigned ys2, uint8_t *dd0, uint8_t *dd1, uint8_t *dd2, unsigned lsd, const uint8_t *ds0, const uint8_t *ds1, const uint8_t *ds2, unsigned lss) { unsigned x, xd, xs, xs2; unsigned id, is; (void)dd1; (void)dd2; for (x=0; x>1) + (ys>>1)*lss/2; u = ds1[is]; v = ds2[is]; ruv = CRV[v]; guv = CGV[v] + CGU[u]; buv = CBU[u]; yuv2rgb555(&dd0[id], ds0[xs + ys*lss], ruv, guv,buv); yuv2rgb555(&dd0[id+2], ds0[xs2 + ys*lss], ruv, guv,buv); yuv2rgb555(&dd0[id + lsd], ds0[xs + ys2*lss], ruv, guv,buv); yuv2rgb555(&dd0[id+2 + lsd], ds0[xs2 + ys2*lss], ruv, guv,buv); } } static void nv12_to_yuv420p(unsigned xoffs, unsigned width, double rw, unsigned yd, unsigned ys, unsigned ys2, uint8_t *dd0, uint8_t *dd1, uint8_t *dd2, unsigned lsd, const uint8_t *ds0, const uint8_t *ds1, const uint8_t *ds2, unsigned lss ) { unsigned x, xd, xs, xs2; unsigned id, is; (void)ds2; for (x=0; x>1) + (ys>>1)*lss/2) & ~1; dd1[id] = ds1[2*is]; dd2[id] = ds1[2*is+1]; } } static void nv21_to_yuv420p(unsigned xoffs, unsigned width, double rw, unsigned yd, unsigned ys, unsigned ys2, uint8_t *dd0, uint8_t *dd1, uint8_t *dd2, unsigned lsd, const uint8_t *ds0, const uint8_t *ds1, const uint8_t *ds2, unsigned lss ) { unsigned x, xd, xs, xs2; unsigned id, is; (void)ds2; for (x=0; x>1) + (ys>>1)*lss/2) & ~1; dd2[id] = ds1[2*is]; dd1[id] = ds1[2*is+1]; } } #define MAX_SRC 9 #define MAX_DST 7 /** * Pixel conversion table: [src][dst] * * @note Index must be aligned to values in enum vidfmt */ static line_h *conv_table[MAX_SRC][MAX_DST] = { /* * Dst: YUV420P YUYV422 UYVY422 RGB32 */ {yuv420p_to_yuv420p, NULL, NULL, yuv420p_to_rgb32, NULL, yuv420p_to_rgb565, yuv420p_to_rgb555}, {yuyv422_to_yuv420p, NULL, NULL, NULL, NULL, NULL, NULL}, {uyvy422_to_yuv420p, NULL, NULL, NULL, NULL, NULL, NULL}, {rgb32_to_yuv420p, NULL, NULL, NULL, NULL, NULL, NULL}, {rgb32_to_yuv420p, NULL, NULL, NULL, NULL, NULL, NULL}, {NULL, NULL, NULL, NULL, NULL, NULL, NULL}, {NULL, NULL, NULL, NULL, NULL, NULL, NULL}, {nv12_to_yuv420p, NULL, NULL, NULL, NULL, NULL, NULL}, {nv21_to_yuv420p, NULL, NULL, NULL, NULL, NULL, NULL}, }; /** * Convert a video frame from one pixel format to another pixel format * * Speed matches swscale: SWS_BILINEAR * * todo: optimize (check out SWS_FAST_BILINEAR) * * @param dst Destination video frame * @param src Source video frame * @param r Drawing area in destination frame, NULL means whole frame */ void vidconv(struct vidframe *dst, const struct vidframe *src, struct vidrect *r) { struct vidrect rdst; unsigned yd, ys, ys2, lsd, lss, y; const uint8_t *ds0, *ds1, *ds2; uint8_t *dd0, *dd1, *dd2; double rw, rh; line_h *lineh = NULL; if (!vidframe_isvalid(dst) || !vidframe_isvalid(src)) return; if (src->fmt < MAX_SRC && dst->fmt < MAX_DST) { /* Lookup conversion function */ lineh = conv_table[src->fmt][dst->fmt]; } if (!lineh) { (void)re_printf("vidconv: no pixel converter found for" " %s -> %s\n", vidfmt_name(src->fmt), vidfmt_name(dst->fmt)); return; } if (r) { r->x &= ~1; r->y &= ~1; r->w &= ~1; r->h &= ~1; if ((r->x + r->w) > dst->size.w || (r->y + r->h) > dst->size.h) { (void)re_printf("vidconv: out of bounds (%u x %u)\n", dst->size.w, dst->size.h); return; } } else { rdst.x = rdst.y = 0; rdst.w = dst->size.w & ~1; rdst.h = dst->size.h & ~1; r = &rdst; } rw = (double)src->size.w / (double)r->w; rh = (double)src->size.h / (double)r->h; lsd = dst->linesize[0]; lss = src->linesize[0]; dd0 = dst->data[0]; dd1 = dst->data[1]; dd2 = dst->data[2]; ds0 = src->data[0]; ds1 = src->data[1]; ds2 = src->data[2]; for (y=0; yh; y+=2) { yd = y + r->y; ys = (unsigned)(y * rh); ys2 = (unsigned)((y+1) * rh); lineh(r->x, r->w, rw, yd, ys, ys2, dd0, dd1, dd2, lsd, ds0, ds1, ds2, lss); } } /** * Same as vidconv(), but maintain source aspect ratio within bounds of r * * @param dst Destination video frame * @param src Source video frame * @param r Drawing area in destination frame */ void vidconv_aspect(struct vidframe *dst, const struct vidframe *src, struct vidrect *r) { struct vidsz asz; double ar; ar = (double)src->size.w / (double)src->size.h; asz.w = r->w; asz.h = r->h; r->w = (unsigned)min((double)asz.w, (double)asz.h * ar); r->h = (unsigned)min((double)asz.h, (double)asz.w / ar); r->x = r->x + (asz.w - r->w) / 2; r->y = r->y + (asz.h - r->h) / 2; vidconv(dst, src, r); } rem-0.4.7/src/aumix/0000755000175100017510000000000012640750470015006 5ustar rkrishnanrkrishnanrem-0.4.7/src/aumix/mod.mk0000644000175100017510000000010711547711207016114 0ustar rkrishnanrkrishnan# # mod.mk # # Copyright (C) 2010 Creytiv.com # SRCS += aumix/aumix.c rem-0.4.7/src/aumix/aumix.c0000644000175100017510000001603312634536643016307 0ustar rkrishnanrkrishnan/** * @file aumix.c Audio Mixer * * Copyright (C) 2010 Creytiv.com */ #define _BSD_SOURCE 1 #define _DEFAULT_SOURCE 1 #include #include #include #include #include #include #include #include /** Defines an Audio mixer */ struct aumix { pthread_mutex_t mutex; pthread_cond_t cond; struct list srcl; pthread_t thread; struct aufile *af; uint32_t ptime; uint32_t frame_size; uint32_t srate; uint8_t ch; bool run; }; /** Defines an Audio mixer source */ struct aumix_source { struct le le; int16_t *frame; struct aubuf *aubuf; struct aumix *mix; aumix_frame_h *fh; void *arg; }; static void dummy_frame_handler(const int16_t *sampv, size_t sampc, void *arg) { (void)sampv; (void)sampc; (void)arg; } static void destructor(void *arg) { struct aumix *mix = arg; if (mix->run) { pthread_mutex_lock(&mix->mutex); mix->run = false; pthread_cond_signal(&mix->cond); pthread_mutex_unlock(&mix->mutex); pthread_join(mix->thread, NULL); } mem_deref(mix->af); } static void source_destructor(void *arg) { struct aumix_source *src = arg; if (src->le.list) { pthread_mutex_lock(&src->mix->mutex); list_unlink(&src->le); pthread_mutex_unlock(&src->mix->mutex); } mem_deref(src->aubuf); mem_deref(src->frame); mem_deref(src->mix); } static void *aumix_thread(void *arg) { uint8_t *silence, *frame, *base_frame; struct aumix *mix = arg; int16_t *mix_frame; uint64_t ts = 0; silence = mem_zalloc(mix->frame_size*2, NULL); frame = mem_alloc(mix->frame_size*2, NULL); mix_frame = mem_alloc(mix->frame_size*2, NULL); if (!silence || !frame || !mix_frame) goto out; pthread_mutex_lock(&mix->mutex); while (mix->run) { struct le *le; uint64_t now; if (!mix->srcl.head) { mix->af = mem_deref(mix->af); pthread_cond_wait(&mix->cond, &mix->mutex); ts = 0; } else { pthread_mutex_unlock(&mix->mutex); (void)usleep(4000); pthread_mutex_lock(&mix->mutex); } now = tmr_jiffies(); if (!ts) ts = now; if (ts > now) continue; if (mix->af) { size_t n = mix->frame_size*2; if (aufile_read(mix->af, frame, &n) || n == 0) { mix->af = mem_deref(mix->af); base_frame = silence; } else if (n < mix->frame_size*2) { memset(frame + n, 0, mix->frame_size*2 - n); mix->af = mem_deref(mix->af); base_frame = frame; } else { base_frame = frame; } } else { base_frame = silence; } for (le=mix->srcl.head; le; le=le->next) { struct aumix_source *src = le->data; aubuf_read_samp(src->aubuf, src->frame, mix->frame_size); } for (le=mix->srcl.head; le; le=le->next) { struct aumix_source *src = le->data; struct le *cle; memcpy(mix_frame, base_frame, mix->frame_size*2); for (cle=mix->srcl.head; cle; cle=cle->next) { struct aumix_source *csrc = cle->data; size_t i; #if 1 /* skip self */ if (csrc == src) continue; #endif for (i=0; iframe_size; i++) mix_frame[i] += csrc->frame[i]; } src->fh(mix_frame, mix->frame_size, src->arg); } ts += mix->ptime; } pthread_mutex_unlock(&mix->mutex); out: mem_deref(mix_frame); mem_deref(silence); mem_deref(frame); return NULL; } /** * Allocate a new Audio mixer * * @param mixp Pointer to allocated audio mixer * @param srate Sample rate in [Hz] * @param ch Number of channels * @param ptime Packet time in [ms] * * @return 0 for success, otherwise error code */ int aumix_alloc(struct aumix **mixp, uint32_t srate, uint8_t ch, uint32_t ptime) { struct aumix *mix; int err; if (!mixp || !srate || !ch || !ptime) return EINVAL; mix = mem_zalloc(sizeof(*mix), destructor); if (!mix) return ENOMEM; mix->ptime = ptime; mix->frame_size = srate * ch * ptime / 1000; mix->srate = srate; mix->ch = ch; err = pthread_mutex_init(&mix->mutex, NULL); if (err) goto out; err = pthread_cond_init(&mix->cond, NULL); if (err) goto out; mix->run = true; err = pthread_create(&mix->thread, NULL, aumix_thread, mix); if (err) { mix->run = false; goto out; } out: if (err) mem_deref(mix); else *mixp = mix; return err; } /** * Load audio file for mixer announcements * * @param mix Audio mixer * @param filepath Filename of audio file with complete path * * @return 0 for success, otherwise error code */ int aumix_playfile(struct aumix *mix, const char *filepath) { struct aufile_prm prm; struct aufile *af; int err; if (!mix || !filepath) return EINVAL; err = aufile_open(&af, &prm, filepath, AUFILE_READ); if (err) return err; if (prm.fmt != AUFMT_S16LE || prm.srate != mix->srate || prm.channels != mix->ch) { mem_deref(af); return EINVAL; } pthread_mutex_lock(&mix->mutex); mem_deref(mix->af); mix->af = af; pthread_mutex_unlock(&mix->mutex); return 0; } /** * Count number of audio sources in the audio mixer * * @param mix Audio mixer * * @return Number of audio sources */ uint32_t aumix_source_count(const struct aumix *mix) { if (!mix) return 0; return list_count(&mix->srcl); } /** * Allocate an audio mixer source * * @param srcp Pointer to allocated audio source * @param mix Audio mixer * @param fh Mixer frame handler * @param arg Handler argument * * @return 0 for success, otherwise error code */ int aumix_source_alloc(struct aumix_source **srcp, struct aumix *mix, aumix_frame_h *fh, void *arg) { struct aumix_source *src; size_t sz; int err; if (!srcp || !mix) return EINVAL; src = mem_zalloc(sizeof(*src), source_destructor); if (!src) return ENOMEM; src->mix = mem_ref(mix); src->fh = fh ? fh : dummy_frame_handler; src->arg = arg; sz = mix->frame_size*2; src->frame = mem_alloc(sz, NULL); if (!src->frame) { err = ENOMEM; goto out; } err = aubuf_alloc(&src->aubuf, sz * 6, sz * 12); if (err) goto out; out: if (err) mem_deref(src); else *srcp = src; return err; } /** * Enable/disable aumix source * * @param src Audio mixer source * @param enable True to enable, false to disable */ void aumix_source_enable(struct aumix_source *src, bool enable) { struct aumix *mix; if (!src) return; if (src->le.list && enable) return; if (!src->le.list && !enable) return; mix = src->mix; pthread_mutex_lock(&mix->mutex); if (enable) { list_append(&mix->srcl, &src->le, src); pthread_cond_signal(&mix->cond); } else { list_unlink(&src->le); } pthread_mutex_unlock(&mix->mutex); } /** * Write PCM samples for a given source to the audio mixer * * @param src Audio mixer source * @param sampv PCM samples * @param sampc Number of samples * * @return 0 for success, otherwise error code */ int aumix_source_put(struct aumix_source *src, const int16_t *sampv, size_t sampc) { if (!src || !sampv) return EINVAL; return aubuf_write_samp(src->aubuf, sampv, sampc); } /** * Flush the audio buffer of a given audio mixer source * * @param src Audio mixer source */ void aumix_source_flush(struct aumix_source *src) { if (!src) return; aubuf_flush(src->aubuf); } rem-0.4.7/src/vid/0000755000175100017510000000000012640750470014445 5ustar rkrishnanrkrishnanrem-0.4.7/src/vid/fmt.c0000644000175100017510000000167012026534573015405 0ustar rkrishnanrkrishnan/** * @file fmt.c Video Formats * * Copyright (C) 2010 Creytiv.com */ #include #include /** Video format description table */ const struct vidfmt_desc vidfmt_descv[VID_FMT_N] = { {"yuv420p", 3, 3, { {0, 1}, {1, 1}, {2, 1}, {0, 0} } }, {"yuyv422", 1, 3, { {0, 2}, {0, 4}, {0, 4}, {0, 0} } }, {"uyvy422", 1, 3, { {0, 2}, {0, 4}, {0, 4}, {0, 0} } }, {"rgb32", 1, 4, { {0, 4}, {0, 4}, {0, 4}, {0, 4} } }, {"argb", 1, 4, { {0, 4}, {0, 4}, {0, 4}, {0, 4} } }, {"rgb565", 1, 3, { {0, 2}, {0, 2}, {0, 2}, {0, 0} } }, {"rgb555", 1, 3, { {0, 2}, {0, 2}, {0, 2}, {0, 0} } }, {"nv12", 3, 2, { {0, 1}, {1, 2}, {1, 2}, {0, 0} } }, {"nv21", 3, 2, { {0, 1}, {1, 2}, {1, 2}, {0, 0} } }, }; /** * Get the name of a video format * * @param fmt Video format * * @return Name of the video format */ const char *vidfmt_name(enum vidfmt fmt) { if (fmt >= VID_FMT_N) return "???"; return vidfmt_descv[fmt].name; } rem-0.4.7/src/vid/frame.c0000644000175100017510000001205012552000027015665 0ustar rkrishnanrkrishnan/** * @file frame.c Video Frame * * Copyright (C) 2010 Creytiv.com */ #include #include #include /** * Get video frame buffer size * * @param fmt Video pixel format * @param sz Size of video frame * * @return Number of bytes */ size_t vidframe_size(enum vidfmt fmt, const struct vidsz *sz) { if (!sz) return 0; switch (fmt) { case VID_FMT_YUV420P: return sz->w * sz->h * 3 / 2; case VID_FMT_YUYV422: return sz->w * sz->h * 2; case VID_FMT_UYVY422: return sz->w * sz->h * 2; case VID_FMT_RGB32: return sz->w * sz->h * 4; case VID_FMT_ARGB: return sz->w * sz->h * 4; case VID_FMT_RGB565: return sz->w * sz->h * 2; case VID_FMT_RGB555: return sz->w * sz->h * 2; case VID_FMT_NV12: return sz->w * sz->h * 3 / 2; case VID_FMT_NV21: return sz->w * sz->h * 3 / 2; default: return 0; } } /** * Initialize a video frame * * @param vf Video frame * @param fmt Video pixel format * @param sz Size of video frame * @param data Pointer to video planes * @param linesize Pointer to linesizes */ void vidframe_init(struct vidframe *vf, enum vidfmt fmt, const struct vidsz *sz, void *data[4], unsigned linesize[4]) { int i; if (!vf || !sz || !data || !linesize) return; for (i=0; i<4; i++) { vf->data[i] = data[i]; vf->linesize[i] = linesize[i]; } vf->size = *sz; vf->fmt = fmt; } /** * Initialize a video frame from a buffer * * @param vf Video frame * @param fmt Video pixel format * @param sz Size of video frame * @param buf Frame buffer */ void vidframe_init_buf(struct vidframe *vf, enum vidfmt fmt, const struct vidsz *sz, uint8_t *buf) { unsigned w, h; if (!vf || !sz || !buf) return; w = (sz->w + 1) >> 1; h = (sz->h + 1) >> 1; memset(vf->linesize, 0, sizeof(vf->linesize)); memset(vf->data, 0, sizeof(vf->data)); switch (fmt) { case VID_FMT_YUV420P: vf->linesize[0] = sz->w; vf->linesize[1] = w; vf->linesize[2] = w; vf->data[0] = buf; vf->data[1] = vf->data[0] + vf->linesize[0] * sz->h; vf->data[2] = vf->data[1] + vf->linesize[1] * h; break; case VID_FMT_YUYV422: case VID_FMT_UYVY422: vf->linesize[0] = sz->w * 2; vf->data[0] = buf; break; case VID_FMT_RGB32: case VID_FMT_ARGB: vf->linesize[0] = sz->w * 4; vf->data[0] = buf; break; case VID_FMT_RGB565: case VID_FMT_RGB555: vf->linesize[0] = sz->w * 2; vf->data[0] = buf; break; case VID_FMT_NV12: case VID_FMT_NV21: vf->linesize[0] = sz->w; vf->linesize[1] = w*2; vf->data[0] = buf; vf->data[1] = vf->data[0] + vf->linesize[0] * sz->h; break; default: (void)re_printf("vidframe: no fmt %s\n", vidfmt_name(fmt)); return; } vf->size = *sz; vf->fmt = fmt; } /** * Allocate an empty video frame * * @param vfp Pointer to allocated video frame * @param fmt Video pixel format * @param sz Size of video frame * * @return 0 for success, otherwise error code */ int vidframe_alloc(struct vidframe **vfp, enum vidfmt fmt, const struct vidsz *sz) { struct vidframe *vf; if (!sz || !sz->w || !sz->h) return EINVAL; vf = mem_zalloc(sizeof(*vf) + vidframe_size(fmt, sz), NULL); if (!vf) return ENOMEM; vidframe_init_buf(vf, fmt, sz, (uint8_t *)(vf + 1)); *vfp = vf; return 0; } /** * Fill a video frame with a nice color * * @param vf Video frame * @param r Red color component * @param g Green color component * @param b Blue color component */ void vidframe_fill(struct vidframe *vf, uint32_t r, uint32_t g, uint32_t b) { uint8_t *p; unsigned h, i; if (!vf) return; switch (vf->fmt) { case VID_FMT_YUV420P: h = vf->size.h; memset(vf->data[0], rgb2y(r, g, b), h * vf->linesize[0]); memset(vf->data[1], rgb2u(r, g, b), h/2 * vf->linesize[1]); memset(vf->data[2], rgb2v(r, g, b), h/2 * vf->linesize[2]); break; case VID_FMT_RGB32: p = vf->data[0]; for (i=0; ilinesize[0] * vf->size.h; i+=4) { *p++ = b; *p++ = g; *p++ = r; *p++ = 0; } break; default: (void)re_printf("vidfill: no fmt %s\n", vidfmt_name(vf->fmt)); break; } } /** * Copy content between to equally sized video frames of same pixel format * * @param dst Destination frame * @param src Source frame */ void vidframe_copy(struct vidframe *dst, const struct vidframe *src) { const uint8_t *ds0, *ds1, *ds2; unsigned lsd, lss, w, h, y; uint8_t *dd0, *dd1, *dd2; if (!dst || !src) return; if (!vidsz_cmp(&dst->size, &src->size)) return; if (dst->fmt != src->fmt) return; switch (dst->fmt) { case VID_FMT_YUV420P: lsd = dst->linesize[0]; lss = src->linesize[0]; dd0 = dst->data[0]; dd1 = dst->data[1]; dd2 = dst->data[2]; ds0 = src->data[0]; ds1 = src->data[1]; ds2 = src->data[2]; w = dst->size.w & ~1; h = dst->size.h & ~1; for (y=0; y #include #include /** * Draw a pixel to a video frame * * @param f Video frame * @param x Pixel X-position * @param y Pixel Y-position * @param r Red color component * @param g Green color component * @param b Blue color component */ void vidframe_draw_point(struct vidframe *f, unsigned x, unsigned y, uint8_t r, uint8_t g, uint8_t b) { uint8_t *yp, *up, *vp, *p; if (!f) return; if (x >= f->size.w || y >= f->size.h) return; switch (f->fmt) { case VID_FMT_YUV420P: yp = f->data[0] + f->linesize[0] * y + x; up = f->data[1] + f->linesize[1] * (y/2) + x/2; vp = f->data[2] + f->linesize[2] * (y/2) + x/2; yp[0] = rgb2y(r, g, b); up[0] = rgb2u(r, g, b); vp[0] = rgb2v(r, g, b); break; case VID_FMT_RGB32: p = f->data[0] + f->linesize[0] * y + x*4; p[0] = b; p[1] = g; p[2] = r; break; default: (void)re_fprintf(stderr, "vidframe_draw_point:" " unsupported format %s\n", vidfmt_name(f->fmt)); break; } } /** * Draw a horizontal line * * @param f Video frame * @param x0 Origin X-position * @param y0 Origin Y-position * @param w Line width * @param r Red color component * @param g Green color component * @param b Blue color component */ void vidframe_draw_hline(struct vidframe *f, unsigned x0, unsigned y0, unsigned w, uint8_t r, uint8_t g, uint8_t b) { if (!f || f->fmt != VID_FMT_YUV420P) return; if (x0 >= f->size.w || y0 >= f->size.h) return; w = min(w, f->size.w-x0); memset(f->data[0] + y0 *f->linesize[0] + x0, rgb2y(r, g, b), w); memset(f->data[1] + (y0/2)*f->linesize[1] + x0/2, rgb2u(r, g, b), w/2); memset(f->data[2] + (y0/2)*f->linesize[2] + x0/2, rgb2v(r, g, b), w/2); } /** * Draw a vertical line * * @param f Video frame * @param x0 Origin X-position * @param y0 Origin Y-position * @param h Line height * @param r Red color component * @param g Green color component * @param b Blue color component */ void vidframe_draw_vline(struct vidframe *f, unsigned x0, unsigned y0, unsigned h, uint8_t r, uint8_t g, uint8_t b) { if (!f) return; while (h--) { vidframe_draw_point(f, x0, y0++, r, g, b); } } /** * Draw a rectangle * * @param f Video frame * @param x0 Origin X-position * @param y0 Origin Y-position * @param w Rectangle width * @param h Rectangle height * @param r Red color component * @param g Green color component * @param b Blue color component */ void vidframe_draw_rect(struct vidframe *f, unsigned x0, unsigned y0, unsigned w, unsigned h, uint8_t r, uint8_t g, uint8_t b) { if (!f) return; vidframe_draw_hline(f, x0, y0, w, r, g, b); vidframe_draw_hline(f, x0, y0+h-1, w, r, g, b); vidframe_draw_vline(f, x0, y0, h, r, g, b); vidframe_draw_vline(f, x0+w-1, y0, h, r, g, b); } rem-0.4.7/src/aufile/0000755000175100017510000000000012640750470015130 5ustar rkrishnanrkrishnanrem-0.4.7/src/aufile/wave.c0000644000175100017510000000702712136043772016244 0ustar rkrishnanrkrishnan/** * @file wave.c WAVE format encoding and decoding * * Copyright (C) 2010 Creytiv.com */ #include #include #include #include #include "aufile.h" enum { WAVE_FMT_SIZE = 16 }; /** WAV-file chunk */ struct wav_chunk { uint8_t id[4]; uint32_t size; }; static int write_u16(FILE *f, uint16_t v) { v = sys_htols(v); if (1 != fwrite(&v, sizeof(v), 1, f)) return ferror(f); return 0; } static int write_u32(FILE *f, uint32_t v) { v = sys_htoll(v); if (1 != fwrite(&v, sizeof(v), 1, f)) return ferror(f); return 0; } static int read_u16(FILE *f, uint16_t *v) { uint16_t vle; if (1 != fread(&vle, sizeof(vle), 1, f)) return ferror(f); *v = sys_ltohs(vle); return 0; } static int read_u32(FILE *f, uint32_t *v) { uint32_t vle; if (1 != fread(&vle, sizeof(vle), 1, f)) return ferror(f); *v = sys_ltohl(vle); return 0; } static int chunk_encode(FILE *f, const char *id, size_t sz) { if (1 != fwrite(id, 4, 1, f)) return ferror(f); return write_u32(f, (uint32_t)sz); } static int chunk_decode(struct wav_chunk *chunk, FILE *f) { if (1 != fread(chunk->id, sizeof(chunk->id), 1, f)) return ferror(f); return read_u32(f, &chunk->size); } int wav_header_encode(FILE *f, uint16_t format, uint16_t channels, uint32_t srate, uint16_t bps, size_t bytes) { int err; err = chunk_encode(f, "RIFF", 36 + bytes); if (err) return err; if (1 != fwrite("WAVE", 4, 1, f)) return ferror(f); err = chunk_encode(f, "fmt ", WAVE_FMT_SIZE); if (err) return err; err = write_u16(f, format); err |= write_u16(f, channels); err |= write_u32(f, srate); err |= write_u32(f, srate * channels * bps / 8); err |= write_u16(f, channels * bps / 8); err |= write_u16(f, bps); if (err) return err; return chunk_encode(f, "data", bytes); } int wav_header_decode(struct wav_fmt *fmt, size_t *datasize, FILE *f) { struct wav_chunk header, format, chunk; uint8_t rifftype[4]; /* "WAVE" */ int err = 0; err = chunk_decode(&header, f); if (err) return err; if (memcmp(header.id, "RIFF", 4)) { (void)re_fprintf(stderr, "aufile: expected RIFF (%b)\n", header.id, sizeof(header.id)); return EBADMSG; } if (1 != fread(rifftype, sizeof(rifftype), 1, f)) return ferror(f); if (memcmp(rifftype, "WAVE", 4)) { (void)re_fprintf(stderr, "aufile: expected WAVE (%b)\n", rifftype, sizeof(rifftype)); return EBADMSG; } err = chunk_decode(&format, f); if (err) return err; if (memcmp(format.id, "fmt ", 4)) { (void)re_fprintf(stderr, "aufile: expected fmt (%b)\n", format.id, sizeof(format.id)); return EBADMSG; } if (format.size < WAVE_FMT_SIZE) return EBADMSG; err = read_u16(f, &fmt->format); err |= read_u16(f, &fmt->channels); err |= read_u32(f, &fmt->srate); err |= read_u32(f, &fmt->byterate); err |= read_u16(f, &fmt->block_align); err |= read_u16(f, &fmt->bps); if (err) return err; /* skip any extra bytes */ if (format.size >= (WAVE_FMT_SIZE + 2)) { err = read_u16(f, &fmt->extra); if (err) return err; if (fmt->extra > 0) { if (fseek(f, fmt->extra, SEEK_CUR)) return errno; } } /* fast forward to "data" chunk */ for (;;) { err = chunk_decode(&chunk, f); if (err) return err; if (chunk.size > header.size) { (void)re_fprintf(stderr, "chunk size too large" " (%u > %u)\n", chunk.size, header.size); return EBADMSG; } if (0 == memcmp(chunk.id, "data", 4)) { *datasize = chunk.size; break; } if (fseek(f, chunk.size, SEEK_CUR) < 0) return errno; } return 0; } rem-0.4.7/src/aufile/aufile.c0000644000175100017510000000741611761617417016557 0ustar rkrishnanrkrishnan/** * @file aufile.c Audio File interface * * Copyright (C) 2010 Creytiv.com */ #include #include #include #include #include "aufile.h" /** Audio file state */ struct aufile { struct aufile_prm prm; enum aufile_mode mode; size_t datasize; size_t nread; size_t nwritten; FILE *f; }; static int wavfmt_to_aufmt(enum wavfmt fmt, uint16_t bps) { switch (fmt) { case WAVE_FMT_PCM: if (bps != 16) return -1; return AUFMT_S16LE; case WAVE_FMT_ALAW: if (bps != 8) return -1; return AUFMT_PCMA; case WAVE_FMT_ULAW: if (bps != 8) return -1; return AUFMT_PCMU; default: return -1; } } static enum wavfmt aufmt_to_wavfmt(enum aufmt fmt) { switch (fmt) { case AUFMT_S16LE: return WAVE_FMT_PCM; case AUFMT_PCMA: return WAVE_FMT_ALAW; case AUFMT_PCMU: return WAVE_FMT_ULAW; default: return -1; } } static uint16_t aufmt_to_bps(enum aufmt fmt) { switch (fmt) { case AUFMT_S16LE: return 16; case AUFMT_PCMA: return 8; case AUFMT_PCMU: return 8; default: return 0; } } static void destructor(void *arg) { struct aufile *af = arg; if (!af->f) return; /* Update WAV header in write-mode */ if (af->mode == AUFILE_WRITE && af->nwritten > 0) { rewind(af->f); (void)wav_header_encode(af->f, aufmt_to_wavfmt(af->prm.fmt), af->prm.channels, af->prm.srate, aufmt_to_bps(af->prm.fmt), af->nwritten); } (void)fclose(af->f); } /** * Open a WAVE file for reading or writing * * Supported formats: 16-bit PCM, A-law, U-law * * @param afp Pointer to allocated Audio file * @param prm Audio format of the file * @param filename Filename of the WAV-file to load * @param mode Read or write mode * * @return 0 if success, otherwise errorcode */ int aufile_open(struct aufile **afp, struct aufile_prm *prm, const char *filename, enum aufile_mode mode) { struct wav_fmt fmt; struct aufile *af; int aufmt; int err; if (!afp || !filename || (mode == AUFILE_WRITE && !prm)) return EINVAL; af = mem_zalloc(sizeof(*af), destructor); if (!af) return ENOMEM; af->mode = mode; af->f = fopen(filename, mode == AUFILE_READ ? "rb" : "wb"); if (!af->f) { err = errno; goto out; } switch (mode) { case AUFILE_READ: err = wav_header_decode(&fmt, &af->datasize, af->f); if (err) goto out; aufmt = wavfmt_to_aufmt(fmt.format, fmt.bps); if (aufmt < 0) { err = ENOSYS; goto out; } if (prm) { prm->srate = fmt.srate; prm->channels = (uint8_t)fmt.channels; prm->fmt = aufmt; } break; case AUFILE_WRITE: af->prm = *prm; err = wav_header_encode(af->f, aufmt_to_wavfmt(prm->fmt), prm->channels, prm->srate, aufmt_to_bps(prm->fmt), 0); break; default: err = ENOSYS; break; } out: if (err) mem_deref(af); else *afp = af; return err; } /** * Read PCM-samples from a WAV file * * @param af Audio-file * @param p Read buffer * @param sz Size of buffer, on return contains actual read * * @return 0 if success, otherwise errorcode */ int aufile_read(struct aufile *af, uint8_t *p, size_t *sz) { size_t n; if (!af || !p || !sz || af->mode != AUFILE_READ) return EINVAL; if (af->nread >= af->datasize) { *sz = 0; return 0; } n = min(*sz, af->datasize - af->nread); n = fread(p, 1, n, af->f); if (ferror(af->f)) return errno; *sz = n; af->nread += n; return 0; } /** * Write PCM-samples to a WAV file * * @param af Audio-file * @param p Write buffer * @param sz Size of buffer * * @return 0 if success, otherwise errorcode */ int aufile_write(struct aufile *af, const uint8_t *p, size_t sz) { if (!af || !p || !sz || af->mode != AUFILE_WRITE) return EINVAL; if (1 != fwrite(p, sz, 1, af->f)) return ferror(af->f); af->nwritten += sz; return 0; } rem-0.4.7/src/aufile/mod.mk0000644000175100017510000000013711713036660016237 0ustar rkrishnanrkrishnan# # mod.mk # # Copyright (C) 2010 Creytiv.com # SRCS += aufile/aufile.c SRCS += aufile/wave.c rem-0.4.7/src/aufile/aufile.h0000644000175100017510000000106311713036660016544 0ustar rkrishnanrkrishnan/** * @file aufile.h Audio File -- internal API * * Copyright (C) 2010 Creytiv.com */ enum wavfmt { WAVE_FMT_PCM = 0x0001, WAVE_FMT_ALAW = 0x0006, WAVE_FMT_ULAW = 0x0007, }; /** WAVE format sub-chunk */ struct wav_fmt { uint16_t format; uint16_t channels; uint32_t srate; uint32_t byterate; uint16_t block_align; uint16_t bps; uint16_t extra; }; int wav_header_encode(FILE *f, uint16_t format, uint16_t channels, uint32_t srate, uint16_t bps, size_t bytes); int wav_header_decode(struct wav_fmt *fmt, size_t *datasize, FILE *f); rem-0.4.7/src/au/0000755000175100017510000000000012640750470014270 5ustar rkrishnanrkrishnanrem-0.4.7/src/au/fmt.c0000644000175100017510000000130712631242053015214 0ustar rkrishnanrkrishnan/** * @file au/fmt.c Audio formats * * Copyright (C) 2010 Creytiv.com */ #include #include /* Number of bytes per sample */ size_t aufmt_sample_size(enum aufmt fmt) { switch (fmt) { case AUFMT_S16LE: return sizeof(int16_t); case AUFMT_PCMA: return 1; case AUFMT_PCMU: return 1; case AUFMT_FLOAT: return sizeof(float); case AUFMT_S24_3LE: return 3; default: return 0; } } const char *aufmt_name(enum aufmt fmt) { switch (fmt) { case AUFMT_S16LE: return "S16LE"; case AUFMT_PCMA: return "PCMA"; case AUFMT_PCMU: return "PCMU"; case AUFMT_FLOAT: return "FLOAT"; case AUFMT_S24_3LE: return "S24_3LE"; default: return "???"; } } rem-0.4.7/src/au/mod.mk0000644000175100017510000000010212631242053015362 0ustar rkrishnanrkrishnan# # mod.mk # # Copyright (C) 2010 Creytiv.com # SRCS += au/fmt.c rem-0.4.7/docs/0000755000175100017510000000000012640750470014024 5ustar rkrishnanrkrishnanrem-0.4.7/docs/ChangeLog0000644000175100017510000000443312634535506015606 0ustar rkrishnanrkrishnan2015-12-13 Alfred E. Heggestad * Version 0.4.7 * build: add pkg-config file (thanks to William King) * auconv: new module for audio sample format conversion (thanks to Ola Palm for testing) * aumix: close file on sleep * vid: added vidframe_copy() * vidmix: pthread_rwlockattr_setkind_np for linux and glibc (patch copied from openwrt repo) 2014-05-18 Alfred E. Heggestad * Version 0.4.6 * debian: update package * include: use quotes to include header files * vidmix: use full picture for 2 participants 2014-01-06 Alfred E. Heggestad * Version 0.4.5 * debian: fix dependency to libre (patch from Juha) * auresamp: improved audio resampler better low-pass FIR-filter coefficients * fir: improved channels-agnostic FIR-filter * vid: vidframe_draw_point() make API take RGB-values handle VID_FMT_ARGB format in all vid-functions vidframe_fill() fix swapped RGB/BGR values 2013-10-03 Alfred E. Heggestad * Version 0.4.4 * debian: fix dependency to libre (patch from Juha) * vid: change type of width/height to 'unsigned' * vidframe: added basic drawing functions 2013-05-05 Alfred E. Heggestad * Version 0.4.3 * aubuf: added API for 16-bit samples * vidconv: added support for NV21 to YUV420P * vidmix: various improvements 2012-09-09 Alfred E. Heggestad * Version 0.4.2 * aubuf: fix bug in aubuf_append() * aumix: change sample type to int16_t * auresamp: change sample API to array of int16_t * vid: change signature of vidframe_size() * vidconv: fix pixel alignment bug * vidmix: enhance API 2012-04-21 Alfred E. Heggestad * Version 0.4.1 * updated doxygen comments * aufile: new module for audio file reading/writing * aumix: various improvements, add aumix_playfile() add function to enable/disable sources added aumix_source_flush() * vidconv: add support for YUV420P to RGB555 fix warning of casting to unaligned access * vidmix: various improvements add function to enable/disable sources 2011-12-25 Alfred E. Heggestad * Version 0.4.0 * vidconv: add support for YUV420P to RGB565 2011-09-07 Alfred E. Heggestad * Version 0.3.0 * Initial Release rem-0.4.7/docs/README0000644000175100017510000000201012631242053014666 0ustar rkrishnanrkrishnanREADME ------ librem - "Audio and video processing media library" Copyright (C) 2010 - 2015 Creytiv.com Distributed under BSD license Audio Modules: name: status: description: * au testing Base audio types * aubuf testing Audio buffer * auconv unstable Audio sample format conversion * aufile testing Audio file reader/writer * aumix unstable Audio mixer * auresamp unstable Audio resampler * autone testing Tone/DTMF generator * g711 stable G.711 audio codec Video Modules: name: status: description: * vid testing Base video types * vidconv testing Colorspace conversion and scaling * vidmix unstable Video mixer Generic modules: * dsp testing DSP routines * fir unstable FIR (Finite Impulse Response) filter Features: * ITU-T G.711 Appendix I and Appendix II External dependencies: libre Feedback: - Please send feedback to rem-0.4.7/docs/COPYING0000644000175100017510000000277712271666670015104 0ustar rkrishnanrkrishnanCopyright (c) 2010 - 2014, Alfred E. Heggestad Copyright (c) 2010 - 2014, Richard Aas Copyright (c) 2010 - 2014, Creytiv.com All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the Creytiv.com nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. rem-0.4.7/rpm/0000755000175100017510000000000012640750470013672 5ustar rkrishnanrkrishnanrem-0.4.7/rpm/rem.spec0000644000175100017510000000206712634535506015342 0ustar rkrishnanrkrishnan%define name rem %define ver 0.4.7 %define rel 1 Summary: Audio and Video processing media library Name: %name Version: %ver Release: %rel License: BSD Group: Applications/Devel Source0: file://%{name}-%{version}.tar.gz URL: http://www.creytiv.com/ Vendor: Creytiv Packager: Alfred E. Heggestad BuildRoot: /var/tmp/%{name}-build-root BuildRequires: re-devel %description Audio and Video processing media library %package devel Summary: librem development files Group: Development/Libraries Requires: %{name} = %{version} %description devel librem development files. %prep %setup %build make RELEASE=1 %install rm -rf $RPM_BUILD_ROOT make DESTDIR=$RPM_BUILD_ROOT install \ %ifarch x86_64 LIBDIR=/usr/lib64 %endif %clean rm -rf $RPM_BUILD_ROOT %post -p /sbin/ldconfig %postun -p /sbin/ldconfig %files %defattr(644,root,root,755) %attr(755,root,root) %{_libdir}/librem*.so* %files devel %defattr(644,root,root,755) %{_includedir}/rem/*.h %{_libdir}/librem*.a %changelog * Wed Sep 7 2011 Alfred E. Heggestad - - Initial build. rem-0.4.7/include/0000755000175100017510000000000012640750470014517 5ustar rkrishnanrkrishnanrem-0.4.7/include/rem_vidmix.h0000644000175100017510000000272612111406557017037 0ustar rkrishnanrkrishnan/** * @file rem_vidmix.h Video Mixer * * Copyright (C) 2010 Creytiv.com */ struct vidmix; struct vidmix_source; /** * Video mixer frame handler * * @param ts Timestamp * @param frame Video frame * @param arg Handler argument */ typedef void (vidmix_frame_h)(uint32_t ts, const struct vidframe *frame, void *arg); int vidmix_alloc(struct vidmix **mixp); int vidmix_source_alloc(struct vidmix_source **srcp, struct vidmix *mix, const struct vidsz *sz, unsigned fps, bool content, vidmix_frame_h *fh, void *arg); bool vidmix_source_isenabled(const struct vidmix_source *src); bool vidmix_source_isrunning(const struct vidmix_source *src); void *vidmix_source_get_focus(const struct vidmix_source *src); void vidmix_source_enable(struct vidmix_source *src, bool enable); int vidmix_source_start(struct vidmix_source *src); void vidmix_source_stop(struct vidmix_source *src); int vidmix_source_set_size(struct vidmix_source *src, const struct vidsz *sz); void vidmix_source_set_rate(struct vidmix_source *src, unsigned fps); void vidmix_source_set_content_hide(struct vidmix_source *src, bool hide); void vidmix_source_toggle_selfview(struct vidmix_source *src); void vidmix_source_set_focus(struct vidmix_source *src, const struct vidmix_source *focus_src, bool focus_full); void vidmix_source_set_focus_idx(struct vidmix_source *src, unsigned pidx); void vidmix_source_put(struct vidmix_source *src, const struct vidframe *frame); rem-0.4.7/include/rem_g711.h0000644000175100017510000000226411625406724016220 0ustar rkrishnanrkrishnan/** * @file rem_g711.h Interface to G.711 codec * * Copyright (C) 2010 Creytiv.com */ extern const uint8_t g711_l2u[4096]; extern const uint8_t g711_l2A[2048]; extern const int16_t g711_u2l[256]; extern const int16_t g711_A2l[256]; /** * Encode one 16-bit PCM sample to U-law format * * @param l Signed PCM sample * * @return U-law byte */ static inline uint8_t g711_pcm2ulaw(int16_t l) { const uint8_t mask = (l < 0) ? 0x7f : 0xff; if (l < 0) l = -l; if (l < 4) return 0xff & mask; l -= 4; l >>= 3; return g711_l2u[l] & mask; } /** * Encode one 16-bit PCM sample to A-law format * * @param l Signed PCM sample * * @return A-law byte */ static inline uint8_t g711_pcm2alaw(int16_t l) { const uint8_t mask = (l < 0) ? 0x7f : 0xff; if (l < 0) l = -l; l >>= 4; return g711_l2A[l] & mask; } /** * Decode one U-law sample to 16-bit PCM sample * * @param u U-law byte * * @return Signed PCM sample */ static inline int16_t g711_ulaw2pcm(uint8_t u) { return g711_u2l[u]; } /** * Decode one A-law sample to 16-bit PCM sample * * @param A A-law byte * * @return Signed PCM sample */ static inline int16_t g711_alaw2pcm(uint8_t a) { return g711_A2l[a]; } rem-0.4.7/include/rem_audio.h0000644000175100017510000000046712631242053016634 0ustar rkrishnanrkrishnan/** * @file rem_audio.h Wrapper for all Audio header files * * Copyright (C) 2010 Creytiv.com */ #include "rem_au.h" #include "rem_aubuf.h" #include "rem_auconv.h" #include "rem_aufile.h" #include "rem_autone.h" #include "rem_aumix.h" #include "rem_fir.h" #include "rem_auresamp.h" #include "rem_g711.h" rem-0.4.7/include/rem_au.h0000644000175100017510000000072112631242053016131 0ustar rkrishnanrkrishnan/** * @file rem_au.h Basic audio types * * Copyright (C) 2010 Creytiv.com */ /** Audio formats */ enum aufmt { AUFMT_S16LE, /**< Signed 16-bit PCM */ AUFMT_PCMA, /**< G.711 A-law */ AUFMT_PCMU, /**< G.711 U-law */ AUFMT_FLOAT, /**< Float 32 bit (CPU endian) */ AUFMT_S24_3LE,/**< Signed 24bit Little Endian in 3bytes format */ }; size_t aufmt_sample_size(enum aufmt fmt); const char *aufmt_name(enum aufmt fmt); rem-0.4.7/include/rem_autone.h0000644000175100017510000000035411607653716017037 0ustar rkrishnanrkrishnan/** * @file rem_autone.h Audio Tones * * Copyright (C) 2010 Creytiv.com */ int autone_sine(struct mbuf *mb, uint32_t srate, uint32_t f1, int l1, uint32_t f2, int l2); int autone_dtmf(struct mbuf *mb, uint32_t srate, int digit); rem-0.4.7/include/rem_vidconv.h0000644000175100017510000000043411631414721017177 0ustar rkrishnanrkrishnan/** * @file rem_vidconv.h Video colorspace conversion * * Copyright (C) 2010 Creytiv.com */ void vidconv(struct vidframe *dst, const struct vidframe *src, struct vidrect *r); void vidconv_aspect(struct vidframe *dst, const struct vidframe *src, struct vidrect *r); rem-0.4.7/include/rem_vid.h0000644000175100017510000000741412552000027016307 0ustar rkrishnanrkrishnan/** * @file rem_vid.h Basic video types * * Copyright (C) 2010 Creytiv.com */ /** Pixel format */ enum vidfmt { VID_FMT_YUV420P = 0, /* planar YUV 4:2:0 12bpp */ VID_FMT_YUYV422, /* packed YUV 4:2:2 16bpp */ VID_FMT_UYVY422, /* packed YUV 4:2:2 16bpp */ VID_FMT_RGB32, /* packed RGBA 8:8:8:8 32bpp (native endian) */ VID_FMT_ARGB, /* packed RGBA 8:8:8:8 32bpp (big endian) */ VID_FMT_RGB565, /* packed RGB 5:6:5 16bpp (native endian) */ VID_FMT_RGB555, /* packed RGB 5:5:5 16bpp (native endian) */ VID_FMT_NV12, /* planar YUV 4:2:0 12bpp UV interleaved */ VID_FMT_NV21, /* planar YUV 4:2:0 12bpp VU interleaved */ /* marker */ VID_FMT_N }; /** Video pixel format component description */ struct vidfmt_compdesc { unsigned plane_index:2; unsigned step:3; }; /** Video pixel format description */ struct vidfmt_desc { const char *name; uint8_t planes; uint8_t compn; struct vidfmt_compdesc compv[4]; }; /** Video orientation */ enum vidorient { VIDORIENT_PORTRAIT, VIDORIENT_PORTRAIT_UPSIDEDOWN, VIDORIENT_LANDSCAPE_LEFT, VIDORIENT_LANDSCAPE_RIGHT, }; /** Video size */ struct vidsz { unsigned w; /**< Width */ unsigned h; /**< Height */ }; /** Video frame */ struct vidframe { uint8_t *data[4]; /**< Video planes */ uint16_t linesize[4]; /**< Array of line-sizes */ struct vidsz size; /**< Frame resolution */ enum vidfmt fmt; /**< Video pixel format */ }; /** Video point */ struct vidpt { unsigned x; /**< X position */ unsigned y; /**< Y position */ }; /** Video rectangle */ struct vidrect { unsigned x; /**< X position */ unsigned y; /**< Y position */ unsigned w; /**< Width */ unsigned h; /**< Height */ }; static inline bool vidsz_cmp(const struct vidsz *a, const struct vidsz *b) { if (!a || !b) return false; if (a == b) return true; return a->w == b->w && a->h == b->h; } static inline bool vidrect_cmp(const struct vidrect *a, const struct vidrect *b) { if (!a || !b) return false; if (a == b) return true; return a->x == b->x && a->y == b->y && a->w == b->w && a->h == b->h; } static inline int rgb2y(uint8_t r, uint8_t g, uint8_t b) { return ((66 * r + 129 * g + 25 * b + 128) >> 8) + 16; } static inline int rgb2u(uint8_t r, uint8_t g, uint8_t b) { return ((-38 * r - 74 * g + 112 * b + 128) >> 8) + 128; } static inline int rgb2v(uint8_t r, uint8_t g, uint8_t b) { return ((112 * r - 94 * g - 18 * b + 128) >> 8) + 128; } size_t vidframe_size(enum vidfmt fmt, const struct vidsz *sz); void vidframe_init(struct vidframe *vf, enum vidfmt fmt, const struct vidsz *sz, void *data[4], unsigned linesize[4]); void vidframe_init_buf(struct vidframe *vf, enum vidfmt fmt, const struct vidsz *sz, uint8_t *buf); int vidframe_alloc(struct vidframe **vfp, enum vidfmt fmt, const struct vidsz *sz); void vidframe_fill(struct vidframe *vf, uint32_t r, uint32_t g, uint32_t b); void vidframe_copy(struct vidframe *dst, const struct vidframe *src); const char *vidfmt_name(enum vidfmt fmt); static inline bool vidframe_isvalid(const struct vidframe *f) { return f ? f->data[0] != NULL : false; } extern const struct vidfmt_desc vidfmt_descv[VID_FMT_N]; /* draw */ void vidframe_draw_point(struct vidframe *f, unsigned x, unsigned y, uint8_t r, uint8_t g, uint8_t b); void vidframe_draw_hline(struct vidframe *f, unsigned x0, unsigned y0, unsigned w, uint8_t r, uint8_t g, uint8_t b); void vidframe_draw_vline(struct vidframe *f, unsigned x0, unsigned y0, unsigned h, uint8_t r, uint8_t g, uint8_t b); void vidframe_draw_rect(struct vidframe *f, unsigned x0, unsigned y0, unsigned w, unsigned h, uint8_t r, uint8_t g, uint8_t b); rem-0.4.7/include/rem_video.h0000644000175100017510000000025612326142471016641 0ustar rkrishnanrkrishnan/** * @file rem_video.h Wrapper for all Video header files * * Copyright (C) 2010 Creytiv.com */ #include "rem_vid.h" #include "rem_vidmix.h" #include "rem_vidconv.h" rem-0.4.7/include/rem_auconv.h0000644000175100017510000000045612631242053017024 0ustar rkrishnanrkrishnan/** * @file rem_auconv.h Audio sample format conversion * * Copyright (C) 2010 Creytiv.com */ void auconv_from_s16(enum aufmt dst_fmt, void *dst_sampv, const int16_t *src_sampv, size_t sampc); void auconv_to_s16(int16_t *dst_sampv, enum aufmt src_fmt, void *src_sampv, size_t sampc); rem-0.4.7/include/rem_aufile.h0000644000175100017510000000101211761617417017000 0ustar rkrishnanrkrishnan/** * @file rem_aufile.h Audio File interface * * Copyright (C) 2010 Creytiv.com */ /** Audio file mode */ enum aufile_mode { AUFILE_READ, AUFILE_WRITE, }; /** Audio file parameters */ struct aufile_prm { uint32_t srate; uint8_t channels; enum aufmt fmt; }; struct aufile; int aufile_open(struct aufile **afp, struct aufile_prm *prm, const char *filename, enum aufile_mode mode); int aufile_read(struct aufile *af, uint8_t *p, size_t *sz); int aufile_write(struct aufile *af, const uint8_t *p, size_t sz); rem-0.4.7/include/rem_fir.h0000644000175100017510000000064012252070337016307 0ustar rkrishnanrkrishnan/** * @file rem_fir.h Finite Impulse Response (FIR) functions * * Copyright (C) 2010 Creytiv.com */ /** Defines the fir filter state */ struct fir { int16_t history[256]; /**< Previous samples */ unsigned index; /**< Sample index */ }; void fir_reset(struct fir *fir); void fir_filter(struct fir *fir, int16_t *outv, const int16_t *inv, size_t inc, unsigned ch, const int16_t *tapv, size_t tapc); rem-0.4.7/include/rem_auresamp.h0000644000175100017510000000210112252070337017336 0ustar rkrishnanrkrishnan/** * @file rem_auresamp.h Audio Resampling * * Copyright (C) 2010 Creytiv.com */ /** * Defines the audio resampler handler * * @param outv Output samples * @param inv Input samples * @param inc Number of input samples * @param ratio Resample ratio */ typedef void (auresamp_h)(int16_t *outv, const int16_t *inv, size_t inc, unsigned ratio); /** Defines the resampler state */ struct auresamp { struct fir fir; /**< FIR filter state */ auresamp_h *resample; /**< Resample handler */ const int16_t *tapv; /**< FIR filter taps */ size_t tapc; /**< FIR filter tap count */ uint32_t orate, irate; /**< Input/output sample rate */ unsigned och, ich; /**< Input/output channel count */ unsigned ratio; /**< Resample ratio */ bool up; /**< Up/down sample flag */ }; void auresamp_init(struct auresamp *rs); int auresamp_setup(struct auresamp *rs, uint32_t irate, unsigned ich, uint32_t orate, unsigned och); int auresamp(struct auresamp *rs, int16_t *outv, size_t *outc, const int16_t *inv, size_t inc); rem-0.4.7/include/rem_aumix.h0000644000175100017510000000152411761617417016666 0ustar rkrishnanrkrishnan/** * @file rem_aumix.h Audio Mixer * * Copyright (C) 2010 Creytiv.com */ struct aumix; struct aumix_source; /** * Audio mixer frame handler * * @param buf Buffer with audio samples * @param sz Number of bytes * @param arg Handler argument */ typedef void (aumix_frame_h)(const int16_t *sampv, size_t sampc, void *arg); int aumix_alloc(struct aumix **mixp, uint32_t srate, uint8_t ch, uint32_t ptime); int aumix_playfile(struct aumix *mix, const char *filepath); uint32_t aumix_source_count(const struct aumix *mix); int aumix_source_alloc(struct aumix_source **srcp, struct aumix *mix, aumix_frame_h *fh, void *arg); void aumix_source_enable(struct aumix_source *src, bool enable); int aumix_source_put(struct aumix_source *src, const int16_t *sampv, size_t sampc); void aumix_source_flush(struct aumix_source *src); rem-0.4.7/include/rem_aubuf.h0000644000175100017510000000200712123033300016612 0ustar rkrishnanrkrishnan/** * @file rem_aubuf.h Audio Buffer * * Copyright (C) 2010 Creytiv.com */ struct aubuf; int aubuf_alloc(struct aubuf **abp, size_t min_sz, size_t max_sz); int aubuf_append(struct aubuf *ab, struct mbuf *mb); int aubuf_write(struct aubuf *ab, const uint8_t *p, size_t sz); void aubuf_read(struct aubuf *ab, uint8_t *p, size_t sz); int aubuf_get(struct aubuf *ab, uint32_t ptime, uint8_t *p, size_t sz); void aubuf_flush(struct aubuf *ab); int aubuf_debug(struct re_printf *pf, const struct aubuf *ab); size_t aubuf_cur_size(const struct aubuf *ab); static inline int aubuf_write_samp(struct aubuf *ab, const int16_t *sampv, size_t sampc) { return aubuf_write(ab, (const uint8_t *)sampv, sampc * 2); } static inline void aubuf_read_samp(struct aubuf *ab, int16_t *sampv, size_t sampc) { aubuf_read(ab, (uint8_t *)sampv, sampc * 2); } static inline int aubuf_get_samp(struct aubuf *ab, uint32_t ptime, int16_t *sampv, size_t sampc) { return aubuf_get(ab, ptime, (uint8_t *)sampv, sampc * 2); } rem-0.4.7/include/rem_dsp.h0000644000175100017510000000426411626676057016342 0ustar rkrishnanrkrishnan/** * @file rem_dsp.h DSP routines * * Copyright (C) 2010 Creytiv.com */ #ifndef UINT8_MAX #define UINT8_MAX (255U) #endif #define INT15_MAX 0x3fff #define INT15_MIN (-INT15_MAX - 1) #ifndef INT16_MAX #define INT16_MAX 0x7fff #endif #ifndef INT16_MIN #define INT16_MIN (-INT16_MAX - 1) #endif /* todo: check which preprocessor macros to use */ #if defined (HAVE_ARMV6) || defined (HAVE_NEON) static inline uint8_t saturate_u8(int32_t a) { uint8_t r; __asm__ __volatile__ ("usat %0, #8, %1" : "=r"(r) : "r"(a)); return r; } static inline int16_t saturate_s15(int32_t a) { __asm__ __volatile__ ("ssat %0, #15, %1 \n\t" : "+r"(a) : "r"(a) ); return a; } static inline int16_t saturate_s16(int32_t a) { __asm__ __volatile__ ("ssat %0, #16, %1 \n\t" : "+r"(a) : "r"(a) ); return a; } static inline int16_t saturate_add16(int32_t a, int32_t b) { __asm__ __volatile__ ("add %0, %1, %2 \n\t" "ssat %0, #16, %0 \n\t" :"+r"(a) :"r"(a), "r"(b) ); return a; } static inline int16_t saturate_sub16(int32_t a, int32_t b) { __asm__ __volatile__ ("sub %0, %1, %2 \n\t" "ssat %0, #16, %0 \n\t" :"+r"(a) :"r"(a), "r"(b) ); return a; } #else static inline uint8_t saturate_u8(int32_t a) { return (a > (int32_t)UINT8_MAX) ? UINT8_MAX : ((a < 0) ? 0 : a); } static inline int16_t saturate_s15(int32_t a) { if (a > INT15_MAX) return INT15_MAX; else if (a < INT15_MIN) return INT15_MIN; else return a; } static inline int16_t saturate_s16(int32_t a) { if (a > INT16_MAX) return INT16_MAX; else if (a < INT16_MIN) return INT16_MIN; else return a; } static inline int16_t saturate_add16(int32_t a, int32_t b) { return saturate_s16(a + b); } static inline int16_t saturate_sub16(int32_t a, int32_t b) { return saturate_s16(a - b); } #endif #ifdef HAVE_NEON static inline int ABS32(int a) { int r; __asm__ __volatile__ ("vmov.s32 d0[0], %1 \t\n" "vabs.s32 d0, d0 \t\n" "vmov.s32 %0, d0[0] \t\n" : "=r"(r) : "r"(a) ); return a; } #else static inline int ABS32(int a) { return a > 0 ? a : -a; } #endif rem-0.4.7/include/rem.h0000644000175100017510000000041412326142471015447 0ustar rkrishnanrkrishnan/** * @file rem.h Wrapper for librem headers * * Copyright (C) 2010 Creytiv.com */ #ifndef REM_H__ #define REM_H__ #ifdef __cplusplus extern "C" { #endif #include "rem_audio.h" #include "rem_video.h" #include "rem_dsp.h" #ifdef __cplusplus } #endif #endif