diff --git a/Makefile.in b/Makefile.in index e198b71ef..251a14cbc 100644 --- a/Makefile.in +++ b/Makefile.in @@ -8,7 +8,7 @@ LINKER = @LINKER@ COMMON_FLAGS = -g @DEFS@ -DPATH_PREFIX=@prefix@ -DLIB_DIR=@libdir@ -Wall -Wextra -Wpointer-arith -msse2 CFLAGS = @CFLAGS@ @X_CFLAGS@ $(COMMON_FLAGS) -D_GNU_SOURCE CPPFLAGS = @CPPFLAGS@ -D_GNU_SOURCE -CXXFLAGS = @CXXFLAGS@ $(COMMON_FLAGS) -D_GNU_SOURCE +CXXFLAGS = @CXXFLAGS@ $(COMMON_FLAGS) -D_GNU_SOURCE NVCCFLAGS = @NVCCFLAGS@ LDFLAGS = @LDFLAGS@ LIBS += @LIBS@ @JACK_TRANS_LIB@ @MATHLIBS@ @COREAUDIO_LIB@ \ diff --git a/config.guess b/config.guess index ed2e03b7f..b79252d6b 100755 --- a/config.guess +++ b/config.guess @@ -1,13 +1,12 @@ #! /bin/sh # Attempt to guess a canonical system name. -# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, -# 2000, 2001, 2002 Free Software Foundation, Inc. +# Copyright 1992-2013 Free Software Foundation, Inc. -timestamp='2002-03-20' +timestamp='2013-06-10' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or +# the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but @@ -16,24 +15,22 @@ timestamp='2002-03-20' # General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# along with this program; if not, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. +# the same distribution terms that you use for the rest of that +# program. This Exception is an additional permission under section 7 +# of the GNU General Public License, version 3 ("GPLv3"). +# +# Originally written by Per Bothner. +# +# You can get the latest version of this script from: +# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD +# +# Please send patches with a ChangeLog entry to config-patches@gnu.org. -# Originally written by Per Bothner . -# Please send patches to . Submit a context -# diff and a properly formatted ChangeLog entry. -# -# This script attempts to guess a canonical system name similar to -# config.sub. If it succeeds, it prints the system name on stdout, and -# exits with 0. Otherwise, it exits with 1. -# -# The plan is that this can be called by configure scripts if you -# don't specify an explicit build system type. me=`echo "$0" | sed -e 's,.*/,,'` @@ -53,8 +50,7 @@ version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. -Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 -Free Software Foundation, Inc. +Copyright 1992-2013 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." @@ -66,11 +62,11 @@ Try \`$me --help' for more information." while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) - echo "$timestamp" ; exit 0 ;; + echo "$timestamp" ; exit ;; --version | -v ) - echo "$version" ; exit 0 ;; + echo "$version" ; exit ;; --help | --h* | -h ) - echo "$usage"; exit 0 ;; + echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. @@ -88,30 +84,42 @@ if test $# != 0; then exit 1 fi +trap 'exit 1' 1 2 15 -dummy=dummy-$$ -trap 'rm -f $dummy.c $dummy.o $dummy.rel $dummy; exit 1' 1 2 15 +# CC_FOR_BUILD -- compiler used by this script. Note that the use of a +# compiler to aid in system detection is discouraged as it requires +# temporary files to be created and, as you can see below, it is a +# headache to deal with in a portable fashion. -# CC_FOR_BUILD -- compiler used by this script. # Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still # use `HOST_CC' if defined, but it is deprecated. -set_cc_for_build='case $CC_FOR_BUILD,$HOST_CC,$CC in - ,,) echo "int dummy(){}" > $dummy.c ; +# Portable tmp directory creation inspired by the Autoconf team. + +set_cc_for_build=' +trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; +trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; +: ${TMPDIR=/tmp} ; + { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || + { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || + { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; +dummy=$tmp/dummy ; +tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; +case $CC_FOR_BUILD,$HOST_CC,$CC in + ,,) echo "int x;" > $dummy.c ; for c in cc gcc c89 c99 ; do - ($c $dummy.c -c -o $dummy.o) >/dev/null 2>&1 ; - if test $? = 0 ; then + if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then CC_FOR_BUILD="$c"; break ; fi ; done ; - rm -f $dummy.c $dummy.o $dummy.rel ; if test x"$CC_FOR_BUILD" = x ; then CC_FOR_BUILD=no_compiler_found ; fi ;; ,,*) CC_FOR_BUILD=$CC ;; ,*,*) CC_FOR_BUILD=$HOST_CC ;; -esac' +esac ; set_cc_for_build= ;' # This is needed to find uname on a Pyramid OSx when run in the BSD universe. # (ghazi@noc.rutgers.edu 1994-08-24) @@ -124,12 +132,33 @@ UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown +case "${UNAME_SYSTEM}" in +Linux|GNU|GNU/*) + # If the system lacks a compiler, then just pick glibc. + # We could probably try harder. + LIBC=gnu + + eval $set_cc_for_build + cat <<-EOF > $dummy.c + #include + #if defined(__UCLIBC__) + LIBC=uclibc + #elif defined(__dietlibc__) + LIBC=dietlibc + #else + LIBC=gnu + #endif + EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'` + ;; +esac + # Note: order is significant - the case branches are not exclusive. case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in *:NetBSD:*:*) # NetBSD (nbsd) targets should (where applicable) match one or - # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, + # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently # switched to ELF, *-*-netbsd* would select the old # object file format. This provides both forward @@ -142,9 +171,11 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ /usr/sbin/$sysctl 2>/dev/null || echo unknown)` case "${UNAME_MACHINE_ARCH}" in + armeb) machine=armeb-unknown ;; arm*) machine=arm-unknown ;; sh3el) machine=shl-unknown ;; sh3eb) machine=sh-unknown ;; + sh5el) machine=sh5le-unknown ;; *) machine=${UNAME_MACHINE_ARCH}-unknown ;; esac # The Operating System including object format, if it has switched @@ -153,7 +184,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in arm*|i386|m68k|ns32k|sh3*|sparc|vax) eval $set_cc_for_build if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ - | grep __ELF__ >/dev/null + | grep -q __ELF__ then # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). # Return netbsd for either. FIX? @@ -163,145 +194,139 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in fi ;; *) - os=netbsd + os=netbsd ;; esac # The OS release - release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + # Debian GNU/NetBSD machines have a different userland, and + # thus, need a distinct triplet. However, they do not need + # kernel version information, so it can be replaced with a + # suitable tag, in the style of linux-gnu. + case "${UNAME_VERSION}" in + Debian*) + release='-gnu' + ;; + *) + release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + ;; + esac # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: # contains redundant information, the shorter form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. echo "${machine}-${os}${release}" - exit 0 ;; - amiga:OpenBSD:*:*) - echo m68k-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - arc:OpenBSD:*:*) - echo mipsel-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - hp300:OpenBSD:*:*) - echo m68k-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - mac68k:OpenBSD:*:*) - echo m68k-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - macppc:OpenBSD:*:*) - echo powerpc-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - mvme68k:OpenBSD:*:*) - echo m68k-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - mvme88k:OpenBSD:*:*) - echo m88k-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - mvmeppc:OpenBSD:*:*) - echo powerpc-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - pmax:OpenBSD:*:*) - echo mipsel-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - sgi:OpenBSD:*:*) - echo mipseb-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - sun3:OpenBSD:*:*) - echo m68k-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - wgrisc:OpenBSD:*:*) - echo mipsel-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; + exit ;; + *:Bitrig:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` + echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE} + exit ;; *:OpenBSD:*:*) - echo ${UNAME_MACHINE}-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; + UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` + echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} + exit ;; + *:ekkoBSD:*:*) + echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} + exit ;; + *:SolidBSD:*:*) + echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} + exit ;; + macppc:MirBSD:*:*) + echo powerpc-unknown-mirbsd${UNAME_RELEASE} + exit ;; + *:MirBSD:*:*) + echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} + exit ;; alpha:OSF1:*:*) - if test $UNAME_RELEASE = "V4.0"; then + case $UNAME_RELEASE in + *4.0) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` - fi + ;; + *5.*) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` + ;; + esac + # According to Compaq, /usr/sbin/psrinfo has been available on + # OSF/1 and Tru64 systems produced since 1995. I hope that + # covers most systems running today. This code pipes the CPU + # types through head -n 1, so we only detect the type of CPU 0. + ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` + case "$ALPHA_CPU_TYPE" in + "EV4 (21064)") + UNAME_MACHINE="alpha" ;; + "EV4.5 (21064)") + UNAME_MACHINE="alpha" ;; + "LCA4 (21066/21068)") + UNAME_MACHINE="alpha" ;; + "EV5 (21164)") + UNAME_MACHINE="alphaev5" ;; + "EV5.6 (21164A)") + UNAME_MACHINE="alphaev56" ;; + "EV5.6 (21164PC)") + UNAME_MACHINE="alphapca56" ;; + "EV5.7 (21164PC)") + UNAME_MACHINE="alphapca57" ;; + "EV6 (21264)") + UNAME_MACHINE="alphaev6" ;; + "EV6.7 (21264A)") + UNAME_MACHINE="alphaev67" ;; + "EV6.8CB (21264C)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8AL (21264B)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8CX (21264D)") + UNAME_MACHINE="alphaev68" ;; + "EV6.9A (21264/EV69A)") + UNAME_MACHINE="alphaev69" ;; + "EV7 (21364)") + UNAME_MACHINE="alphaev7" ;; + "EV7.9 (21364A)") + UNAME_MACHINE="alphaev79" ;; + esac + # A Pn.n version is a patched version. # A Vn.n version is a released version. # A Tn.n version is a released field test version. # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. - cat <$dummy.s - .data -\$Lformat: - .byte 37,100,45,37,120,10,0 # "%d-%x\n" - - .text - .globl main - .align 4 - .ent main -main: - .frame \$30,16,\$26,0 - ldgp \$29,0(\$27) - .prologue 1 - .long 0x47e03d80 # implver \$0 - lda \$2,-1 - .long 0x47e20c21 # amask \$2,\$1 - lda \$16,\$Lformat - mov \$0,\$17 - not \$1,\$18 - jsr \$26,printf - ldgp \$29,0(\$26) - mov 0,\$16 - jsr \$26,exit - .end main -EOF - eval $set_cc_for_build - $CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null - if test "$?" = 0 ; then - case `./$dummy` in - 0-0) - UNAME_MACHINE="alpha" - ;; - 1-0) - UNAME_MACHINE="alphaev5" - ;; - 1-1) - UNAME_MACHINE="alphaev56" - ;; - 1-101) - UNAME_MACHINE="alphapca56" - ;; - 2-303) - UNAME_MACHINE="alphaev6" - ;; - 2-307) - UNAME_MACHINE="alphaev67" - ;; - 2-1307) - UNAME_MACHINE="alphaev68" - ;; - esac - fi - rm -f $dummy.s $dummy - echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` - exit 0 ;; + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + # Reset EXIT trap before exiting to avoid spurious non-zero exit code. + exitcode=$? + trap '' 0 + exit $exitcode ;; Alpha\ *:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # Should we change UNAME_MACHINE based on the output of uname instead # of the specific Alpha model? echo alpha-pc-interix - exit 0 ;; + exit ;; 21064:Windows_NT:50:3) echo alpha-dec-winnt3.5 - exit 0 ;; + exit ;; Amiga*:UNIX_System_V:4.0:*) echo m68k-unknown-sysv4 - exit 0;; + exit ;; *:[Aa]miga[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-amigaos - exit 0 ;; + exit ;; *:[Mm]orph[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-morphos - exit 0 ;; + exit ;; *:OS/390:*:*) echo i370-ibm-openedition - exit 0 ;; + exit ;; + *:z/VM:*:*) + echo s390-ibm-zvmoe + exit ;; + *:OS400:*:*) + echo powerpc-ibm-os400 + exit ;; arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) echo arm-acorn-riscix${UNAME_RELEASE} - exit 0;; + exit ;; + arm*:riscos:*:*|arm*:RISCOS:*:*) + echo arm-unknown-riscos + exit ;; SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) echo hppa1.1-hitachi-hiuxmpp - exit 0;; + exit ;; Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. if test "`(/bin/universe) 2>/dev/null`" = att ; then @@ -309,25 +334,51 @@ EOF else echo pyramid-pyramid-bsd fi - exit 0 ;; + exit ;; NILE*:*:*:dcosx) echo pyramid-pyramid-svr4 - exit 0 ;; + exit ;; + DRS?6000:unix:4.0:6*) + echo sparc-icl-nx6 + exit ;; + DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) + case `/usr/bin/uname -p` in + sparc) echo sparc-icl-nx7; exit ;; + esac ;; + s390x:SunOS:*:*) + echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; sun4H:SunOS:5.*:*) echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit 0 ;; + exit ;; sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit 0 ;; - i86pc:SunOS:5.*:*) - echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit 0 ;; + exit ;; + i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) + echo i386-pc-auroraux${UNAME_RELEASE} + exit ;; + i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) + eval $set_cc_for_build + SUN_ARCH="i386" + # If there is a compiler, see if it is configured for 64-bit objects. + # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. + # This test works for both compilers. + if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then + if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + SUN_ARCH="x86_64" + fi + fi + echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; sun4*:SunOS:6*:*) # According to config.sub, this is the proper way to canonicalize # SunOS6. Hard to guess exactly what SunOS6 will be like, but # it's likely to be more like Solaris than SunOS4. echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit 0 ;; + exit ;; sun4*:SunOS:*:*) case "`/usr/bin/arch -k`" in Series*|S4*) @@ -336,10 +387,10 @@ EOF esac # Japanese Language versions have a version number like `4.1.3-JL'. echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` - exit 0 ;; + exit ;; sun3*:SunOS:*:*) echo m68k-sun-sunos${UNAME_RELEASE} - exit 0 ;; + exit ;; sun*:*:4.2BSD:*) UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 @@ -351,10 +402,10 @@ EOF echo sparc-sun-sunos${UNAME_RELEASE} ;; esac - exit 0 ;; + exit ;; aushp:SunOS:*:*) echo sparc-auspex-sunos${UNAME_RELEASE} - exit 0 ;; + exit ;; # The situation for MiNT is a little confusing. The machine name # can be virtually everything (everything which is not # "atarist" or "atariste" at least should have a processor @@ -364,38 +415,41 @@ EOF # MiNT. But MiNT is downward compatible to TOS, so this should # be no problem. atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} - exit 0 ;; + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} - exit 0 ;; + exit ;; *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} - exit 0 ;; + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) - echo m68k-milan-mint${UNAME_RELEASE} - exit 0 ;; + echo m68k-milan-mint${UNAME_RELEASE} + exit ;; hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) - echo m68k-hades-mint${UNAME_RELEASE} - exit 0 ;; + echo m68k-hades-mint${UNAME_RELEASE} + exit ;; *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) - echo m68k-unknown-mint${UNAME_RELEASE} - exit 0 ;; + echo m68k-unknown-mint${UNAME_RELEASE} + exit ;; + m68k:machten:*:*) + echo m68k-apple-machten${UNAME_RELEASE} + exit ;; powerpc:machten:*:*) echo powerpc-apple-machten${UNAME_RELEASE} - exit 0 ;; + exit ;; RISC*:Mach:*:*) echo mips-dec-mach_bsd4.3 - exit 0 ;; + exit ;; RISC*:ULTRIX:*:*) echo mips-dec-ultrix${UNAME_RELEASE} - exit 0 ;; + exit ;; VAX*:ULTRIX*:*:*) echo vax-dec-ultrix${UNAME_RELEASE} - exit 0 ;; + exit ;; 2020:CLIX:*:* | 2430:CLIX:*:*) echo clipper-intergraph-clix${UNAME_RELEASE} - exit 0 ;; + exit ;; mips:*:*:UMIPS | mips:*:*:RISCos) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c @@ -419,30 +473,36 @@ EOF exit (-1); } EOF - $CC_FOR_BUILD $dummy.c -o $dummy \ - && ./$dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \ - && rm -f $dummy.c $dummy && exit 0 - rm -f $dummy.c $dummy + $CC_FOR_BUILD -o $dummy $dummy.c && + dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && + SYSTEM_NAME=`$dummy $dummyarg` && + { echo "$SYSTEM_NAME"; exit; } echo mips-mips-riscos${UNAME_RELEASE} - exit 0 ;; + exit ;; Motorola:PowerMAX_OS:*:*) echo powerpc-motorola-powermax - exit 0 ;; + exit ;; + Motorola:*:4.3:PL8-*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) + echo powerpc-harris-powermax + exit ;; Night_Hawk:Power_UNIX:*:*) echo powerpc-harris-powerunix - exit 0 ;; + exit ;; m88k:CX/UX:7*:*) echo m88k-harris-cxux7 - exit 0 ;; + exit ;; m88k:*:4*:R4*) echo m88k-motorola-sysv4 - exit 0 ;; + exit ;; m88k:*:3*:R3*) echo m88k-motorola-sysv3 - exit 0 ;; + exit ;; AViiON:dgux:*:*) - # DG/UX returns AViiON for all architectures - UNAME_PROCESSOR=`/usr/bin/uname -p` + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] then if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ @@ -455,29 +515,29 @@ EOF else echo i586-dg-dgux${UNAME_RELEASE} fi - exit 0 ;; + exit ;; M88*:DolphinOS:*:*) # DolphinOS (SVR3) echo m88k-dolphin-sysv3 - exit 0 ;; + exit ;; M88*:*:R3*:*) # Delta 88k system running SVR3 echo m88k-motorola-sysv3 - exit 0 ;; + exit ;; XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) echo m88k-tektronix-sysv3 - exit 0 ;; + exit ;; Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) echo m68k-tektronix-bsd - exit 0 ;; + exit ;; *:IRIX*:*:*) echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` - exit 0 ;; + exit ;; ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. - echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id - exit 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id + exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' i*86:AIX:*:*) echo i386-ibm-aix - exit 0 ;; + exit ;; ia64:AIX:*:*) if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` @@ -485,7 +545,7 @@ EOF IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} - exit 0 ;; + exit ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then eval $set_cc_for_build @@ -500,16 +560,19 @@ EOF exit(0); } EOF - $CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm -f $dummy.c $dummy && exit 0 - rm -f $dummy.c $dummy - echo rs6000-ibm-aix3.2.5 + if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` + then + echo "$SYSTEM_NAME" + else + echo rs6000-ibm-aix3.2.5 + fi elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then echo rs6000-ibm-aix3.2.4 else echo rs6000-ibm-aix3.2 fi - exit 0 ;; - *:AIX:*:[45]) + exit ;; + *:AIX:*:[4567]) IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then IBM_ARCH=rs6000 @@ -522,28 +585,28 @@ EOF IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${IBM_ARCH}-ibm-aix${IBM_REV} - exit 0 ;; + exit ;; *:AIX:*:*) echo rs6000-ibm-aix - exit 0 ;; + exit ;; ibmrt:4.4BSD:*|romp-ibm:BSD:*) echo romp-ibm-bsd4.4 - exit 0 ;; + exit ;; ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to - exit 0 ;; # report: romp-ibm BSD 4.3 + exit ;; # report: romp-ibm BSD 4.3 *:BOSX:*:*) echo rs6000-bull-bosx - exit 0 ;; + exit ;; DPX/2?00:B.O.S.:*:*) echo m68k-bull-sysv3 - exit 0 ;; + exit ;; 9000/[34]??:4.3bsd:1.*:*) echo m68k-hp-bsd - exit 0 ;; + exit ;; hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) echo m68k-hp-bsd4.4 - exit 0 ;; + exit ;; 9000/[34678]??:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` case "${UNAME_MACHINE}" in @@ -552,64 +615,84 @@ EOF 9000/[678][0-9][0-9]) if [ -x /usr/bin/getconf ]; then sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` - sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` - case "${sc_cpu_version}" in - 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 - 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 - 532) # CPU_PA_RISC2_0 - case "${sc_kernel_bits}" in - 32) HP_ARCH="hppa2.0n" ;; - 64) HP_ARCH="hppa2.0w" ;; + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case "${sc_cpu_version}" in + 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 + 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case "${sc_kernel_bits}" in + 32) HP_ARCH="hppa2.0n" ;; + 64) HP_ARCH="hppa2.0w" ;; '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 - esac ;; - esac + esac ;; + esac fi if [ "${HP_ARCH}" = "" ]; then eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c + sed 's/^ //' << EOF >$dummy.c - #define _HPUX_SOURCE - #include - #include + #define _HPUX_SOURCE + #include + #include - int main () - { - #if defined(_SC_KERNEL_BITS) - long bits = sysconf(_SC_KERNEL_BITS); - #endif - long cpu = sysconf (_SC_CPU_VERSION); + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); - switch (cpu) - { - case CPU_PA_RISC1_0: puts ("hppa1.0"); break; - case CPU_PA_RISC1_1: puts ("hppa1.1"); break; - case CPU_PA_RISC2_0: - #if defined(_SC_KERNEL_BITS) - switch (bits) - { - case 64: puts ("hppa2.0w"); break; - case 32: puts ("hppa2.0n"); break; - default: puts ("hppa2.0"); break; - } break; - #else /* !defined(_SC_KERNEL_BITS) */ - puts ("hppa2.0"); break; - #endif - default: puts ("hppa1.0"); break; - } - exit (0); - } + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } EOF - (CCOPTS= $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null) && HP_ARCH=`./$dummy` - if test -z "$HP_ARCH"; then HP_ARCH=hppa; fi - rm -f $dummy.c $dummy + (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` + test -z "$HP_ARCH" && HP_ARCH=hppa fi ;; esac + if [ ${HP_ARCH} = "hppa2.0w" ] + then + eval $set_cc_for_build + + # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating + # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler + # generating 64-bit code. GNU and HP use different nomenclature: + # + # $ CC_FOR_BUILD=cc ./config.guess + # => hppa2.0w-hp-hpux11.23 + # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess + # => hppa64-hp-hpux11.23 + + if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | + grep -q __LP64__ + then + HP_ARCH="hppa2.0w" + else + HP_ARCH="hppa64" + fi + fi echo ${HP_ARCH}-hp-hpux${HPUX_REV} - exit 0 ;; + exit ;; ia64:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` echo ia64-hp-hpux${HPUX_REV} - exit 0 ;; + exit ;; 3050*:HI-UX:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c @@ -637,160 +720,176 @@ EOF exit (0); } EOF - $CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm -f $dummy.c $dummy && exit 0 - rm -f $dummy.c $dummy + $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } echo unknown-hitachi-hiuxwe2 - exit 0 ;; + exit ;; 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) echo hppa1.1-hp-bsd - exit 0 ;; + exit ;; 9000/8??:4.3bsd:*:*) echo hppa1.0-hp-bsd - exit 0 ;; + exit ;; *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) echo hppa1.0-hp-mpeix - exit 0 ;; + exit ;; hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) echo hppa1.1-hp-osf - exit 0 ;; + exit ;; hp8??:OSF1:*:*) echo hppa1.0-hp-osf - exit 0 ;; + exit ;; i*86:OSF1:*:*) if [ -x /usr/sbin/sysversion ] ; then echo ${UNAME_MACHINE}-unknown-osf1mk else echo ${UNAME_MACHINE}-unknown-osf1 fi - exit 0 ;; + exit ;; parisc*:Lites*:*:*) echo hppa1.1-hp-lites - exit 0 ;; + exit ;; C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) echo c1-convex-bsd - exit 0 ;; + exit ;; C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi - exit 0 ;; + exit ;; C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) echo c34-convex-bsd - exit 0 ;; + exit ;; C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) echo c38-convex-bsd - exit 0 ;; + exit ;; C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) echo c4-convex-bsd - exit 0 ;; + exit ;; CRAY*Y-MP:*:*:*) echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit 0 ;; + exit ;; CRAY*[A-Z]90:*:*:*) echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ -e 's/\.[^.]*$/.X/' - exit 0 ;; + exit ;; CRAY*TS:*:*:*) echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit 0 ;; - CRAY*T3D:*:*:*) - echo alpha-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit 0 ;; + exit ;; CRAY*T3E:*:*:*) echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit 0 ;; + exit ;; CRAY*SV1:*:*:*) echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit 0 ;; + exit ;; + *:UNICOS/mp:*:*) + echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` - FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` - FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` - echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" - exit 0 ;; + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + 5000:UNIX_System_V:4.*:*) + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` + echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} - exit 0 ;; + exit ;; sparc*:BSD/OS:*:*) echo sparc-unknown-bsdi${UNAME_RELEASE} - exit 0 ;; + exit ;; *:BSD/OS:*:*) echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} - exit 0 ;; + exit ;; *:FreeBSD:*:*) - echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` - exit 0 ;; + UNAME_PROCESSOR=`/usr/bin/uname -p` + case ${UNAME_PROCESSOR} in + amd64) + echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + *) + echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + esac + exit ;; i*:CYGWIN*:*) echo ${UNAME_MACHINE}-pc-cygwin - exit 0 ;; - i*:MINGW*:*) + exit ;; + *:MINGW64*:*) + echo ${UNAME_MACHINE}-pc-mingw64 + exit ;; + *:MINGW*:*) echo ${UNAME_MACHINE}-pc-mingw32 - exit 0 ;; + exit ;; + i*:MSYS*:*) + echo ${UNAME_MACHINE}-pc-msys + exit ;; + i*:windows32*:*) + # uname -m includes "-pc" on this system. + echo ${UNAME_MACHINE}-mingw32 + exit ;; i*:PW*:*) echo ${UNAME_MACHINE}-pc-pw32 - exit 0 ;; - x86:Interix*:3*) - echo i386-pc-interix3 - exit 0 ;; + exit ;; + *:Interix*:*) + case ${UNAME_MACHINE} in + x86) + echo i586-pc-interix${UNAME_RELEASE} + exit ;; + authenticamd | genuineintel | EM64T) + echo x86_64-unknown-interix${UNAME_RELEASE} + exit ;; + IA64) + echo ia64-unknown-interix${UNAME_RELEASE} + exit ;; + esac ;; + [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) + echo i${UNAME_MACHINE}-pc-mks + exit ;; + 8664:Windows_NT:*) + echo x86_64-pc-mks + exit ;; i*:Windows_NT*:* | Pentium*:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we # UNAME_MACHINE based on the output of uname instead of i386? - echo i386-pc-interix - exit 0 ;; + echo i586-pc-interix + exit ;; i*:UWIN*:*) echo ${UNAME_MACHINE}-pc-uwin - exit 0 ;; + exit ;; + amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) + echo x86_64-unknown-cygwin + exit ;; p*:CYGWIN*:*) echo powerpcle-unknown-cygwin - exit 0 ;; + exit ;; prep*:SunOS:5.*:*) echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit 0 ;; + exit ;; *:GNU:*:*) - echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` - exit 0 ;; + # the GNU system + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit ;; + *:GNU/*:*:*) + # other systems with GNU libc and userland + echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC} + exit ;; i*86:Minix:*:*) echo ${UNAME_MACHINE}-pc-minix - exit 0 ;; - arm*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit 0 ;; - ia64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit 0 ;; - m68*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit 0 ;; - mips:Linux:*:*) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #undef CPU - #undef mips - #undef mipsel - #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) - CPU=mipsel - #else - #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) - CPU=mips - #else - CPU= - #endif - #endif -EOF - eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=` - rm -f $dummy.c - test x"${CPU}" != x && echo "${CPU}-pc-linux-gnu" && exit 0 - ;; - ppc:Linux:*:*) - echo powerpc-unknown-linux-gnu - exit 0 ;; - ppc64:Linux:*:*) - echo powerpc64-unknown-linux-gnu - exit 0 ;; + exit ;; + aarch64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + aarch64_be:Linux:*:*) + UNAME_MACHINE=aarch64_be + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; alpha:Linux:*:*) case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in EV5) UNAME_MACHINE=alphaev5 ;; @@ -800,102 +899,166 @@ EOF EV6) UNAME_MACHINE=alphaev6 ;; EV67) UNAME_MACHINE=alphaev67 ;; EV68*) UNAME_MACHINE=alphaev68 ;; - esac - objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null - if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi - echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} - exit 0 ;; - parisc:Linux:*:* | hppa:Linux:*:*) - # Look for CPU level - case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in - PA7*) echo hppa1.1-unknown-linux-gnu ;; - PA8*) echo hppa2.0-unknown-linux-gnu ;; - *) echo hppa-unknown-linux-gnu ;; esac - exit 0 ;; - parisc64:Linux:*:* | hppa64:Linux:*:*) - echo hppa64-unknown-linux-gnu - exit 0 ;; - s390:Linux:*:* | s390x:Linux:*:*) - echo ${UNAME_MACHINE}-ibm-linux - exit 0 ;; - sh*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit 0 ;; - sparc:Linux:*:* | sparc64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit 0 ;; - x86_64:Linux:*:*) - echo x86_64-unknown-linux-gnu - exit 0 ;; + objdump --private-headers /bin/sh | grep -q ld.so.1 + if test "$?" = 0 ; then LIBC="gnulibc1" ; fi + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + arc:Linux:*:* | arceb:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + arm*:Linux:*:*) + eval $set_cc_for_build + if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_EABI__ + then + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + else + if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_PCS_VFP + then + echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi + else + echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf + fi + fi + exit ;; + avr32*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + cris:Linux:*:*) + echo ${UNAME_MACHINE}-axis-linux-${LIBC} + exit ;; + crisv32:Linux:*:*) + echo ${UNAME_MACHINE}-axis-linux-${LIBC} + exit ;; + frv:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + hexagon:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; i*86:Linux:*:*) - # The BFD linker knows what the default object file format is, so - # first see if it will tell us. cd to the root directory to prevent - # problems with other programs or directories called `ld' in the path. - # Set LC_ALL=C to ensure ld outputs messages in English. - ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \ - | sed -ne '/supported targets:/!d - s/[ ][ ]*/ /g - s/.*supported targets: *// - s/ .*// - p'` - case "$ld_supported_targets" in - elf32-i386) - TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" - ;; - a.out-i386-linux) - echo "${UNAME_MACHINE}-pc-linux-gnuaout" - exit 0 ;; - coff-i386) - echo "${UNAME_MACHINE}-pc-linux-gnucoff" - exit 0 ;; - "") - # Either a pre-BFD a.out linker (linux-gnuoldld) or - # one that does not give us useful --help. - echo "${UNAME_MACHINE}-pc-linux-gnuoldld" - exit 0 ;; - esac - # Determine whether the default compiler is a.out or elf + echo ${UNAME_MACHINE}-pc-linux-${LIBC} + exit ;; + ia64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + m32r*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + m68*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + mips:Linux:*:* | mips64:Linux:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c - #include - #ifdef __ELF__ - # ifdef __GLIBC__ - # if __GLIBC__ >= 2 - LIBC=gnu - # else - LIBC=gnulibc1 - # endif - # else - LIBC=gnulibc1 - # endif + #undef CPU + #undef ${UNAME_MACHINE} + #undef ${UNAME_MACHINE}el + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=${UNAME_MACHINE}el #else - #ifdef __INTEL_COMPILER - LIBC=gnu + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=${UNAME_MACHINE} #else - LIBC=gnuaout + CPU= #endif #endif EOF - eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=` - rm -f $dummy.c - test x"${LIBC}" != x && echo "${UNAME_MACHINE}-pc-linux-${LIBC}" && exit 0 - test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0 + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` + test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; } ;; + or1k:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + or32:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + padre:Linux:*:*) + echo sparc-unknown-linux-${LIBC} + exit ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-${LIBC} + exit ;; + parisc:Linux:*:* | hppa:Linux:*:*) + # Look for CPU level + case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in + PA7*) echo hppa1.1-unknown-linux-${LIBC} ;; + PA8*) echo hppa2.0-unknown-linux-${LIBC} ;; + *) echo hppa-unknown-linux-${LIBC} ;; + esac + exit ;; + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-${LIBC} + exit ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-${LIBC} + exit ;; + ppc64le:Linux:*:*) + echo powerpc64le-unknown-linux-${LIBC} + exit ;; + ppcle:Linux:*:*) + echo powerpcle-unknown-linux-${LIBC} + exit ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo ${UNAME_MACHINE}-ibm-linux-${LIBC} + exit ;; + sh64*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + sh*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + tile*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + vax:Linux:*:*) + echo ${UNAME_MACHINE}-dec-linux-${LIBC} + exit ;; + x86_64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + xtensa*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; i*86:DYNIX/ptx:4*:*) # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. # earlier versions are messed up and put the nodename in both # sysname and nodename. echo i386-sequent-sysv4 - exit 0 ;; + exit ;; i*86:UNIX_SV:4.2MP:2.*) - # Unixware is an offshoot of SVR4, but it has its own version - # number series starting with 2... - # I am not positive that other SVR4 systems won't match this, + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, # I just have to hope. -- rms. - # Use sysv4.2uw... so that sysv4* matches it. + # Use sysv4.2uw... so that sysv4* matches it. echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} - exit 0 ;; + exit ;; + i*86:OS/2:*:*) + # If we were able to find `uname', then EMX Unix compatibility + # is probably installed. + echo ${UNAME_MACHINE}-pc-os2-emx + exit ;; + i*86:XTS-300:*:STOP) + echo ${UNAME_MACHINE}-unknown-stop + exit ;; + i*86:atheos:*:*) + echo ${UNAME_MACHINE}-unknown-atheos + exit ;; + i*86:syllable:*:*) + echo ${UNAME_MACHINE}-pc-syllable + exit ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) + echo i386-unknown-lynxos${UNAME_RELEASE} + exit ;; + i*86:*DOS:*:*) + echo ${UNAME_MACHINE}-pc-msdosdjgpp + exit ;; i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then @@ -903,99 +1066,113 @@ EOF else echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} fi - exit 0 ;; - i*86:*:5:[78]*) + exit ;; + i*86:*:5:[678]*) + # UnixWare 7.x, OpenUNIX and OpenServer 6. case `/bin/uname -X | grep "^Machine"` in *486*) UNAME_MACHINE=i486 ;; *Pentium) UNAME_MACHINE=i586 ;; *Pent*|*Celeron) UNAME_MACHINE=i686 ;; esac echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} - exit 0 ;; + exit ;; i*86:*:3.2:*) if test -f /usr/options/cb.name; then UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then - UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')` - (/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486 - (/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \ + UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` + (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ && UNAME_MACHINE=i586 - (/bin/uname -X|egrep '^Machine.*Pent ?II' >/dev/null) \ + (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ && UNAME_MACHINE=i686 - (/bin/uname -X|egrep '^Machine.*Pentium Pro' >/dev/null) \ + (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ && UNAME_MACHINE=i686 echo ${UNAME_MACHINE}-pc-sco$UNAME_REL else echo ${UNAME_MACHINE}-pc-sysv32 fi - exit 0 ;; - i*86:*DOS:*:*) - echo ${UNAME_MACHINE}-pc-msdosdjgpp - exit 0 ;; + exit ;; pc:*:*:*) # Left here for compatibility: - # uname -m prints for DJGPP always 'pc', but it prints nothing about - # the processor, so we play safe by assuming i386. - echo i386-pc-msdosdjgpp - exit 0 ;; + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i586. + # Note: whatever this is, it MUST be the same as what config.sub + # prints for the "djgpp" host, or else GDB configury will decide that + # this is a cross-build. + echo i586-pc-msdosdjgpp + exit ;; Intel:Mach:3*:*) echo i386-pc-mach3 - exit 0 ;; + exit ;; paragon:*:*:*) echo i860-intel-osf1 - exit 0 ;; + exit ;; i860:*:4.*:*) # i860-SVR4 if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 else # Add other i860-SVR4 vendors below as they are discovered. echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 fi - exit 0 ;; + exit ;; mini*:CTIX:SYS*5:*) # "miniframe" echo m68010-convergent-sysv - exit 0 ;; - M68*:*:R3V[567]*:*) - test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;; - 3[34]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0) + exit ;; + mc68k:UNIX:SYSTEM5:3.51m) + echo m68k-convergent-sysv + exit ;; + M680?0:D-NIX:5.3:*) + echo m68k-diab-dnix + exit ;; + M68*:*:R3V[5678]*:*) + test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; + 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) OS_REL='' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && echo i486-ncr-sysv4.3${OS_REL} && exit 0 + && { echo i486-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ - && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;; + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) - /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && echo i486-ncr-sysv4 && exit 0 ;; + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4; exit; } ;; + NCR*:*:4.2:* | MPRAS*:*:4.2:*) + OS_REL='.3' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) echo m68k-unknown-lynxos${UNAME_RELEASE} - exit 0 ;; + exit ;; mc68030:UNIX_System_V:4.*:*) echo m68k-atari-sysv4 - exit 0 ;; - i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*) - echo i386-unknown-lynxos${UNAME_RELEASE} - exit 0 ;; + exit ;; TSUNAMI:LynxOS:2.*:*) echo sparc-unknown-lynxos${UNAME_RELEASE} - exit 0 ;; + exit ;; rs6000:LynxOS:2.*:*) echo rs6000-unknown-lynxos${UNAME_RELEASE} - exit 0 ;; - PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*) + exit ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) echo powerpc-unknown-lynxos${UNAME_RELEASE} - exit 0 ;; + exit ;; SM[BE]S:UNIX_SV:*:*) echo mips-dde-sysv${UNAME_RELEASE} - exit 0 ;; + exit ;; RM*:ReliantUNIX-*:*:*) echo mips-sni-sysv4 - exit 0 ;; + exit ;; RM*:SINIX-*:*:*) echo mips-sni-sysv4 - exit 0 ;; + exit ;; *:SINIX-*:*:*) if uname -p 2>/dev/null >/dev/null ; then UNAME_MACHINE=`(uname -p) 2>/dev/null` @@ -1003,61 +1180,99 @@ EOF else echo ns32k-sni-sysv fi - exit 0 ;; - PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort - # says - echo i586-unisys-sysv4 - exit 0 ;; + exit ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit ;; *:UNIX_System_V:4*:FTX*) # From Gerald Hewes . # How about differentiating between stratus architectures? -djm echo hppa1.1-stratus-sysv4 - exit 0 ;; + exit ;; *:*:*:FTX*) # From seanf@swdc.stratus.com. echo i860-stratus-sysv4 - exit 0 ;; + exit ;; + i*86:VOS:*:*) + # From Paul.Green@stratus.com. + echo ${UNAME_MACHINE}-stratus-vos + exit ;; *:VOS:*:*) # From Paul.Green@stratus.com. echo hppa1.1-stratus-vos - exit 0 ;; + exit ;; mc68*:A/UX:*:*) echo m68k-apple-aux${UNAME_RELEASE} - exit 0 ;; + exit ;; news*:NEWS-OS:6*:*) echo mips-sony-newsos6 - exit 0 ;; + exit ;; R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) if [ -d /usr/nec ]; then - echo mips-nec-sysv${UNAME_RELEASE} + echo mips-nec-sysv${UNAME_RELEASE} else - echo mips-unknown-sysv${UNAME_RELEASE} + echo mips-unknown-sysv${UNAME_RELEASE} fi - exit 0 ;; + exit ;; BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. echo powerpc-be-beos - exit 0 ;; + exit ;; BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. echo powerpc-apple-beos - exit 0 ;; + exit ;; BePC:BeOS:*:*) # BeOS running on Intel PC compatible. echo i586-pc-beos - exit 0 ;; + exit ;; + BePC:Haiku:*:*) # Haiku running on Intel PC compatible. + echo i586-pc-haiku + exit ;; + x86_64:Haiku:*:*) + echo x86_64-unknown-haiku + exit ;; SX-4:SUPER-UX:*:*) echo sx4-nec-superux${UNAME_RELEASE} - exit 0 ;; + exit ;; SX-5:SUPER-UX:*:*) echo sx5-nec-superux${UNAME_RELEASE} - exit 0 ;; + exit ;; + SX-6:SUPER-UX:*:*) + echo sx6-nec-superux${UNAME_RELEASE} + exit ;; + SX-7:SUPER-UX:*:*) + echo sx7-nec-superux${UNAME_RELEASE} + exit ;; + SX-8:SUPER-UX:*:*) + echo sx8-nec-superux${UNAME_RELEASE} + exit ;; + SX-8R:SUPER-UX:*:*) + echo sx8r-nec-superux${UNAME_RELEASE} + exit ;; Power*:Rhapsody:*:*) echo powerpc-apple-rhapsody${UNAME_RELEASE} - exit 0 ;; + exit ;; *:Rhapsody:*:*) echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} - exit 0 ;; + exit ;; *:Darwin:*:*) - echo `uname -p`-apple-darwin${UNAME_RELEASE} - exit 0 ;; + UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown + eval $set_cc_for_build + if test "$UNAME_PROCESSOR" = unknown ; then + UNAME_PROCESSOR=powerpc + fi + if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then + if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + case $UNAME_PROCESSOR in + i386) UNAME_PROCESSOR=x86_64 ;; + powerpc) UNAME_PROCESSOR=powerpc64 ;; + esac + fi + fi + echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} + exit ;; *:procnto*:*:* | *:QNX:[0123456789]*:*) UNAME_PROCESSOR=`uname -p` if test "$UNAME_PROCESSOR" = "x86"; then @@ -1065,22 +1280,28 @@ EOF UNAME_MACHINE=pc fi echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} - exit 0 ;; + exit ;; *:QNX:*:4*) echo i386-pc-qnx - exit 0 ;; - NSR-[GKLNPTVW]:NONSTOP_KERNEL:*:*) + exit ;; + NEO-?:NONSTOP_KERNEL:*:*) + echo neo-tandem-nsk${UNAME_RELEASE} + exit ;; + NSE-*:NONSTOP_KERNEL:*:*) + echo nse-tandem-nsk${UNAME_RELEASE} + exit ;; + NSR-?:NONSTOP_KERNEL:*:*) echo nsr-tandem-nsk${UNAME_RELEASE} - exit 0 ;; + exit ;; *:NonStop-UX:*:*) echo mips-compaq-nonstopux - exit 0 ;; + exit ;; BS2000:POSIX*:*:*) echo bs2000-siemens-sysv - exit 0 ;; + exit ;; DS/*:UNIX_System_V:*:*) echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} - exit 0 ;; + exit ;; *:Plan9:*:*) # "uname -m" is not consistent, so use $cputype instead. 386 # is converted to i386 for consistency with other x86 @@ -1091,41 +1312,55 @@ EOF UNAME_MACHINE="$cputype" fi echo ${UNAME_MACHINE}-unknown-plan9 - exit 0 ;; - i*86:OS/2:*:*) - # If we were able to find `uname', then EMX Unix compatibility - # is probably installed. - echo ${UNAME_MACHINE}-pc-os2-emx - exit 0 ;; + exit ;; *:TOPS-10:*:*) echo pdp10-unknown-tops10 - exit 0 ;; + exit ;; *:TENEX:*:*) echo pdp10-unknown-tenex - exit 0 ;; + exit ;; KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) echo pdp10-dec-tops20 - exit 0 ;; + exit ;; XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) echo pdp10-xkl-tops20 - exit 0 ;; + exit ;; *:TOPS-20:*:*) echo pdp10-unknown-tops20 - exit 0 ;; + exit ;; *:ITS:*:*) echo pdp10-unknown-its - exit 0 ;; - i*86:XTS-300:*:STOP) - echo ${UNAME_MACHINE}-unknown-stop - exit 0 ;; - i*86:atheos:*:*) - echo ${UNAME_MACHINE}-unknown-atheos - exit 0 ;; + exit ;; + SEI:*:*:SEIUX) + echo mips-sei-seiux${UNAME_RELEASE} + exit ;; + *:DragonFly:*:*) + echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit ;; + *:*VMS:*:*) + UNAME_MACHINE=`(uname -p) 2>/dev/null` + case "${UNAME_MACHINE}" in + A*) echo alpha-dec-vms ; exit ;; + I*) echo ia64-dec-vms ; exit ;; + V*) echo vax-dec-vms ; exit ;; + esac ;; + *:XENIX:*:SysV) + echo i386-pc-xenix + exit ;; + i*86:skyos:*:*) + echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' + exit ;; + i*86:rdos:*:*) + echo ${UNAME_MACHINE}-pc-rdos + exit ;; + i*86:AROS:*:*) + echo ${UNAME_MACHINE}-pc-aros + exit ;; + x86_64:VMkernel:*:*) + echo ${UNAME_MACHINE}-unknown-esx + exit ;; esac -#echo '(No uname command or uname output not recognized.)' 1>&2 -#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 - eval $set_cc_for_build cat >$dummy.c < printf ("m68k-sony-newsos%s\n", #ifdef NEWSOS4 - "4" + "4" #else - "" + "" #endif - ); exit (0); + ); exit (0); #endif #endif #if defined (__arm) && defined (__acorn) && defined (__unix) - printf ("arm-acorn-riscix"); exit (0); + printf ("arm-acorn-riscix\n"); exit (0); #endif #if defined (hp300) && !defined (hpux) @@ -1241,12 +1476,12 @@ main () } EOF -$CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy && rm -f $dummy.c $dummy && exit 0 -rm -f $dummy.c $dummy +$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } # Apollos put the system type in the environment. -test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; } +test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } # Convex versions that predate uname can use getsysinfo(1) @@ -1255,22 +1490,22 @@ then case `getsysinfo -f cpu_type` in c1*) echo c1-convex-bsd - exit 0 ;; + exit ;; c2*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi - exit 0 ;; + exit ;; c34*) echo c34-convex-bsd - exit 0 ;; + exit ;; c38*) echo c38-convex-bsd - exit 0 ;; + exit ;; c4*) echo c4-convex-bsd - exit 0 ;; + exit ;; esac fi @@ -1281,7 +1516,9 @@ This script, last modified $timestamp, has failed to recognize the operating system you are using. It is advised that you download the most up to date version of the config scripts from - ftp://ftp.gnu.org/pub/gnu/config/ + http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD +and + http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD If the version you run ($0) is already up to date, please send the following data and any information you think might be diff --git a/config.sub b/config.sub index f3657978c..9633db704 100755 --- a/config.sub +++ b/config.sub @@ -1,42 +1,40 @@ #! /bin/sh # Configuration validation subroutine script. -# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, -# 2000, 2001, 2002 Free Software Foundation, Inc. +# Copyright 1992-2013 Free Software Foundation, Inc. -timestamp='2002-03-07' +timestamp='2013-08-10' -# This file is (in principle) common to ALL GNU software. -# The presence of a machine in this file suggests that SOME GNU software -# can handle that machine. It does not imply ALL GNU software can. -# -# This file is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, -# Boston, MA 02111-1307, USA. - +# along with this program; if not, see . +# # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. +# the same distribution terms that you use for the rest of that +# program. This Exception is an additional permission under section 7 +# of the GNU General Public License, version 3 ("GPLv3"). -# Please send patches to . Submit a context -# diff and a properly formatted ChangeLog entry. + +# Please send patches with a ChangeLog entry to config-patches@gnu.org. # # Configuration subroutine to validate and canonicalize a configuration type. # Supply the specified configuration type as an argument. # If it is invalid, we print an error message on stderr and exit with code 1. # Otherwise, we print the canonical config type on stdout and succeed. +# You can get the latest version of this script from: +# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD + # This file is supposed to be the same for all GNU packages # and recognize all the CPU types, system types and aliases # that are meaningful with *any* GNU software. @@ -70,8 +68,7 @@ Report bugs and patches to ." version="\ GNU config.sub ($timestamp) -Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 -Free Software Foundation, Inc. +Copyright 1992-2013 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." @@ -83,11 +80,11 @@ Try \`$me --help' for more information." while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) - echo "$timestamp" ; exit 0 ;; + echo "$timestamp" ; exit ;; --version | -v ) - echo "$version" ; exit 0 ;; + echo "$version" ; exit ;; --help | --h* | -h ) - echo "$usage"; exit 0 ;; + echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. @@ -99,7 +96,7 @@ while test $# -gt 0 ; do *local*) # First pass through any local machine types. echo $1 - exit 0;; + exit ;; * ) break ;; @@ -118,10 +115,18 @@ esac # Here we must recognize all the valid KERNEL-OS combinations. maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` case $maybe_os in - nto-qnx* | linux-gnu* | storm-chaos* | os2-emx* | windows32-* | rtmk-nova*) + nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ + linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ + knetbsd*-gnu* | netbsd*-gnu* | \ + kopensolaris*-gnu* | \ + storm-chaos* | os2-emx* | rtmk-nova*) os=-$maybe_os basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` ;; + android-linux) + os=-linux-android + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown + ;; *) basic_machine=`echo $1 | sed 's/-[^-]*$//'` if [ $basic_machine != $1 ] @@ -144,10 +149,13 @@ case $os in -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ - -apple | -axis) + -apple | -axis | -knuth | -cray | -microblaze*) os= basic_machine=$1 ;; + -bluegene*) + os=-cnk + ;; -sim | -cisco | -oki | -wec | -winbond) os= basic_machine=$1 @@ -162,13 +170,17 @@ case $os in os=-chorusos basic_machine=$1 ;; - -chorusrdb) - os=-chorusrdb + -chorusrdb) + os=-chorusrdb basic_machine=$1 - ;; + ;; -hiux*) os=-hiuxwe2 ;; + -sco6) + os=-sco5v6 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; -sco5) os=-sco3.2v5 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` @@ -185,6 +197,10 @@ case $os in # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; + -sco5v6*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; -sco*) os=-sco3.2v2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` @@ -202,6 +218,12 @@ case $os in -isc*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; + -lynx*178) + os=-lynxos178 + ;; + -lynx*5) + os=-lynxos5 + ;; -lynx*) os=-lynxos ;; @@ -226,43 +248,106 @@ case $basic_machine in # Some are omitted here because they have special meanings below. 1750a | 580 \ | a29k \ + | aarch64 | aarch64_be \ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ - | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \ - | c4x | clipper \ - | d10v | d30v | dsp16xx \ - | fr30 \ + | am33_2.0 \ + | arc | arceb \ + | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \ + | avr | avr32 \ + | be32 | be64 \ + | bfin \ + | c4x | c8051 | clipper \ + | d10v | d30v | dlx | dsp16xx \ + | epiphany \ + | fido | fr30 | frv \ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | hexagon \ | i370 | i860 | i960 | ia64 \ - | m32r | m68000 | m68k | m88k | mcore \ - | mips | mips16 | mips64 | mips64el | mips64orion | mips64orionel \ - | mips64vr4100 | mips64vr4100el | mips64vr4300 \ - | mips64vr4300el | mips64vr5000 | mips64vr5000el \ - | mipsbe | mipseb | mipsel | mipsle | mipstx39 | mipstx39el \ - | mipsisa32 | mipsisa64 \ + | ip2k | iq2000 \ + | le32 | le64 \ + | lm32 \ + | m32c | m32r | m32rle | m68000 | m68k | m88k \ + | maxq | mb | microblaze | microblazeel | mcore | mep | metag \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | mips16 \ + | mips64 | mips64el \ + | mips64octeon | mips64octeonel \ + | mips64orion | mips64orionel \ + | mips64r5900 | mips64r5900el \ + | mips64vr | mips64vrel \ + | mips64vr4100 | mips64vr4100el \ + | mips64vr4300 | mips64vr4300el \ + | mips64vr5000 | mips64vr5000el \ + | mips64vr5900 | mips64vr5900el \ + | mipsisa32 | mipsisa32el \ + | mipsisa32r2 | mipsisa32r2el \ + | mipsisa64 | mipsisa64el \ + | mipsisa64r2 | mipsisa64r2el \ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ + | mipsr5900 | mipsr5900el \ + | mipstx39 | mipstx39el \ | mn10200 | mn10300 \ + | moxie \ + | mt \ + | msp430 \ + | nds32 | nds32le | nds32be \ + | nios | nios2 | nios2eb | nios2el \ | ns16k | ns32k \ - | openrisc | or32 \ + | open8 \ + | or1k | or32 \ | pdp10 | pdp11 | pj | pjl \ - | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ + | powerpc | powerpc64 | powerpc64le | powerpcle \ | pyramid \ - | sh | sh[34] | sh[34]eb | shbe | shle | sh64 \ - | sparc | sparc64 | sparc86x | sparclet | sparclite | sparcv9 | sparcv9b \ - | strongarm \ - | tahoe | thumb | tic80 | tron \ - | v850 | v850e \ + | rl78 | rx \ + | score \ + | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ + | sh64 | sh64le \ + | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ + | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ + | spu \ + | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ + | ubicom32 \ + | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ | we32k \ - | x86 | xscale | xstormy16 | xtensa \ - | z8k) + | x86 | xc16x | xstormy16 | xtensa \ + | z8k | z80) basic_machine=$basic_machine-unknown ;; - m6811 | m68hc11 | m6812 | m68hc12) - # Motorola 68HC11/12. + c54x) + basic_machine=tic54x-unknown + ;; + c55x) + basic_machine=tic55x-unknown + ;; + c6x) + basic_machine=tic6x-unknown + ;; + m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | picochip) basic_machine=$basic_machine-unknown os=-none ;; m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) ;; + ms1) + basic_machine=mt-unknown + ;; + + strongarm | thumb | xscale) + basic_machine=arm-unknown + ;; + xgate) + basic_machine=$basic_machine-unknown + os=-none + ;; + xscaleeb) + basic_machine=armeb-unknown + ;; + + xscaleel) + basic_machine=armel-unknown + ;; # We use `pc' rather than `unknown' # because (1) that's what they normally are, and @@ -278,43 +363,82 @@ case $basic_machine in # Recognize the basic CPU types with company name. 580-* \ | a29k-* \ + | aarch64-* | aarch64_be-* \ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ - | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ - | arm-* | armbe-* | armle-* | armv*-* \ - | avr-* \ - | bs2000-* \ - | c[123]* | c30-* | [cjt]90-* | c54x-* \ - | clipper-* | cydra-* \ - | d10v-* | d30v-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \ + | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ + | avr-* | avr32-* \ + | be32-* | be64-* \ + | bfin-* | bs2000-* \ + | c[123]* | c30-* | [cjt]90-* | c4x-* \ + | c8051-* | clipper-* | craynv-* | cydra-* \ + | d10v-* | d30v-* | dlx-* \ | elxsi-* \ - | f30[01]-* | f700-* | fr30-* | fx80-* \ + | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ | h8300-* | h8500-* \ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ + | hexagon-* \ | i*86-* | i860-* | i960-* | ia64-* \ - | m32r-* \ + | ip2k-* | iq2000-* \ + | le32-* | le64-* \ + | lm32-* \ + | m32c-* | m32r-* | m32rle-* \ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ - | m88110-* | m88k-* | mcore-* \ - | mips-* | mips16-* | mips64-* | mips64el-* | mips64orion-* \ - | mips64orionel-* | mips64vr4100-* | mips64vr4100el-* \ - | mips64vr4300-* | mips64vr4300el-* | mipsbe-* | mipseb-* \ - | mipsle-* | mipsel-* | mipstx39-* | mipstx39el-* \ + | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \ + | microblaze-* | microblazeel-* \ + | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ + | mips16-* \ + | mips64-* | mips64el-* \ + | mips64octeon-* | mips64octeonel-* \ + | mips64orion-* | mips64orionel-* \ + | mips64r5900-* | mips64r5900el-* \ + | mips64vr-* | mips64vrel-* \ + | mips64vr4100-* | mips64vr4100el-* \ + | mips64vr4300-* | mips64vr4300el-* \ + | mips64vr5000-* | mips64vr5000el-* \ + | mips64vr5900-* | mips64vr5900el-* \ + | mipsisa32-* | mipsisa32el-* \ + | mipsisa32r2-* | mipsisa32r2el-* \ + | mipsisa64-* | mipsisa64el-* \ + | mipsisa64r2-* | mipsisa64r2el-* \ + | mipsisa64sb1-* | mipsisa64sb1el-* \ + | mipsisa64sr71k-* | mipsisa64sr71kel-* \ + | mipsr5900-* | mipsr5900el-* \ + | mipstx39-* | mipstx39el-* \ + | mmix-* \ + | mt-* \ + | msp430-* \ + | nds32-* | nds32le-* | nds32be-* \ + | nios-* | nios2-* | nios2eb-* | nios2el-* \ | none-* | np1-* | ns16k-* | ns32k-* \ + | open8-* \ | orion-* \ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ - | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ | pyramid-* \ - | romp-* | rs6000-* \ - | sh-* | sh[34]-* | sh[34]eb-* | shbe-* | shle-* | sh64-* \ - | sparc-* | sparc64-* | sparc86x-* | sparclet-* | sparclite-* \ - | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \ - | tahoe-* | thumb-* | tic30-* | tic54x-* | tic80-* | tron-* \ - | v850-* | v850e-* | vax-* \ + | rl78-* | romp-* | rs6000-* | rx-* \ + | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ + | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ + | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ + | sparclite-* \ + | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \ + | tahoe-* \ + | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ + | tile*-* \ + | tron-* \ + | ubicom32-* \ + | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ + | vax-* \ | we32k-* \ - | x86-* | x86_64-* | xps100-* | xscale-* | xstormy16-* \ - | xtensa-* \ + | x86-* | x86_64-* | xc16x-* | xps100-* \ + | xstormy16-* | xtensa*-* \ | ymp-* \ - | z8k-*) + | z8k-* | z80-*) + ;; + # Recognize the basic CPU types without company name, with glob match. + xtensa*) + basic_machine=$basic_machine-unknown ;; # Recognize the various machine names and aliases which stand # for a CPU type and a company and sometimes even an OS. @@ -332,6 +456,9 @@ case $basic_machine in basic_machine=a29k-amd os=-udi ;; + abacus) + basic_machine=abacus-unknown + ;; adobe68k) basic_machine=m68010-adobe os=-scout @@ -346,6 +473,12 @@ case $basic_machine in basic_machine=a29k-none os=-bsd ;; + amd64) + basic_machine=x86_64-pc + ;; + amd64-*) + basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; amdahl) basic_machine=580-amdahl os=-sysv @@ -369,6 +502,10 @@ case $basic_machine in basic_machine=m68k-apollo os=-bsd ;; + aros) + basic_machine=i386-pc + os=-aros + ;; aux) basic_machine=m68k-apple os=-aux @@ -377,10 +514,35 @@ case $basic_machine in basic_machine=ns32k-sequent os=-dynix ;; + blackfin) + basic_machine=bfin-unknown + os=-linux + ;; + blackfin-*) + basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + bluegene*) + basic_machine=powerpc-ibm + os=-cnk + ;; + c54x-*) + basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c55x-*) + basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c6x-*) + basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; c90) basic_machine=c90-cray os=-unicos ;; + cegcc) + basic_machine=arm-unknown + os=-cegcc + ;; convex-c1) basic_machine=c1-convex os=-bsd @@ -405,12 +567,27 @@ case $basic_machine in basic_machine=j90-cray os=-unicos ;; + craynv) + basic_machine=craynv-cray + os=-unicosmp + ;; + cr16 | cr16-*) + basic_machine=cr16-unknown + os=-elf + ;; crds | unos) basic_machine=m68k-crds ;; + crisv32 | crisv32-* | etraxfs*) + basic_machine=crisv32-axis + ;; cris | cris-* | etrax*) basic_machine=cris-axis ;; + crx) + basic_machine=crx-unknown + os=-elf + ;; da30 | da30-*) basic_machine=m68k-da30 ;; @@ -433,6 +610,14 @@ case $basic_machine in basic_machine=m88k-motorola os=-sysv3 ;; + dicos) + basic_machine=i686-pc + os=-dicos + ;; + djgpp) + basic_machine=i586-pc + os=-msdosdjgpp + ;; dpx20 | dpx20-*) basic_machine=rs6000-bull os=-bosx @@ -544,7 +729,6 @@ case $basic_machine in i370-ibm* | ibm*) basic_machine=i370-ibm ;; -# I'm not sure what "Sysv32" means. Should this be sysv3.2? i*86v32) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv32 @@ -583,6 +767,14 @@ case $basic_machine in basic_machine=m68k-isi os=-sysv ;; + m68knommu) + basic_machine=m68k-unknown + os=-linux + ;; + m68knommu-*) + basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; m88k-omron*) basic_machine=m88k-omron ;; @@ -594,10 +786,21 @@ case $basic_machine in basic_machine=ns32k-utek os=-sysv ;; + microblaze*) + basic_machine=microblaze-xilinx + ;; + mingw64) + basic_machine=x86_64-pc + os=-mingw64 + ;; mingw32) - basic_machine=i386-pc + basic_machine=i686-pc os=-mingw32 ;; + mingw32ce) + basic_machine=arm-unknown + os=-mingw32ce + ;; miniframe) basic_machine=m68000-convergent ;; @@ -611,10 +814,6 @@ case $basic_machine in mips3*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown ;; - mmix*) - basic_machine=mmix-knuth - os=-mmixware - ;; monitor) basic_machine=m68k-rom68k os=-coff @@ -627,10 +826,21 @@ case $basic_machine in basic_machine=i386-pc os=-msdos ;; + ms1-*) + basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` + ;; + msys) + basic_machine=i686-pc + os=-msys + ;; mvs) basic_machine=i370-ibm os=-mvs ;; + nacl) + basic_machine=le32-unknown + os=-nacl + ;; ncr3000) basic_machine=i486-ncr os=-sysv4 @@ -695,6 +905,12 @@ case $basic_machine in np1) basic_machine=np1-gould ;; + neo-tandem) + basic_machine=neo-tandem + ;; + nse-tandem) + basic_machine=nse-tandem + ;; nsr-tandem) basic_machine=nsr-tandem ;; @@ -702,9 +918,12 @@ case $basic_machine in basic_machine=hppa1.1-oki os=-proelf ;; - or32 | or32-*) + openrisc | openrisc-*) basic_machine=or32-unknown - os=-coff + ;; + os400) + basic_machine=powerpc-ibm + os=-os400 ;; OSE68000 | ose68000) basic_machine=m68000-ericsson @@ -722,55 +941,76 @@ case $basic_machine in basic_machine=i860-intel os=-osf ;; + parisc) + basic_machine=hppa-unknown + os=-linux + ;; + parisc-*) + basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; pbd) basic_machine=sparc-tti ;; pbb) basic_machine=m68k-tti ;; - pc532 | pc532-*) + pc532 | pc532-*) basic_machine=ns32k-pc532 ;; + pc98) + basic_machine=i386-pc + ;; + pc98-*) + basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; pentium | p5 | k5 | k6 | nexgen | viac3) basic_machine=i586-pc ;; - pentiumpro | p6 | 6x86 | athlon) + pentiumpro | p6 | 6x86 | athlon | athlon_*) basic_machine=i686-pc ;; - pentiumii | pentium2) + pentiumii | pentium2 | pentiumiii | pentium3) basic_machine=i686-pc ;; + pentium4) + basic_machine=i786-pc + ;; pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumpro-* | p6-* | 6x86-* | athlon-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; - pentiumii-* | pentium2-*) + pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; + pentium4-*) + basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; pn) basic_machine=pn-gould ;; power) basic_machine=power-ibm ;; - ppc) basic_machine=powerpc-unknown - ;; - ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + ppc | ppcbe) basic_machine=powerpc-unknown + ;; + ppc-* | ppcbe-*) + basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppcle | powerpclittle | ppc-le | powerpc-little) basic_machine=powerpcle-unknown - ;; + ;; ppcle-* | powerpclittle-*) basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64) basic_machine=powerpc64-unknown - ;; + ;; ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64le | powerpc64little | ppc64-le | powerpc64-little) basic_machine=powerpc64le-unknown - ;; + ;; ppc64le-* | powerpc64little-*) basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` ;; @@ -781,6 +1021,14 @@ case $basic_machine in basic_machine=i586-unknown os=-pw32 ;; + rdos | rdos64) + basic_machine=x86_64-pc + os=-rdos + ;; + rdos32) + basic_machine=i386-pc + os=-rdos + ;; rom68k) basic_machine=m68k-rom68k os=-coff @@ -801,6 +1049,20 @@ case $basic_machine in basic_machine=a29k-amd os=-udi ;; + sb1) + basic_machine=mipsisa64sb1-unknown + ;; + sb1el) + basic_machine=mipsisa64sb1el-unknown + ;; + sde) + basic_machine=mipsisa32-sde + os=-elf + ;; + sei) + basic_machine=mips-sei + os=-seiux + ;; sequent) basic_machine=i386-sequent ;; @@ -808,6 +1070,12 @@ case $basic_machine in basic_machine=sh-hitachi os=-hms ;; + sh5el) + basic_machine=sh5le-unknown + ;; + sh64) + basic_machine=sh64-unknown + ;; sparclite-wrs | simso-wrs) basic_machine=sparclite-wrs os=-vxworks @@ -826,6 +1094,9 @@ case $basic_machine in basic_machine=i860-stratus os=-sysv4 ;; + strongarm-* | thumb-*) + basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; sun2) basic_machine=m68000-sun ;; @@ -866,7 +1137,7 @@ case $basic_machine in sun386 | sun386i | roadrunner) basic_machine=i386-sun ;; - sv1) + sv1) basic_machine=sv1-cray os=-unicos ;; @@ -874,10 +1145,6 @@ case $basic_machine in basic_machine=i386-sequent os=-dynix ;; - t3d) - basic_machine=alpha-cray - os=-unicos - ;; t3e) basic_machine=alphaev5-cray os=-unicos @@ -886,9 +1153,9 @@ case $basic_machine in basic_machine=t90-cray os=-unicos ;; - tic54x | c54x*) - basic_machine=tic54x-unknown - os=-coff + tile*) + basic_machine=$basic_machine-unknown + os=-linux-gnu ;; tx39) basic_machine=mipstx39-unknown @@ -903,6 +1170,10 @@ case $basic_machine in tower | tower-32) basic_machine=m68k-ncr ;; + tpf) + basic_machine=s390x-ibm + os=-tpf + ;; udi29k) basic_machine=a29k-amd os=-udi @@ -924,8 +1195,8 @@ case $basic_machine in os=-vms ;; vpp*|vx|vx-*) - basic_machine=f301-fujitsu - ;; + basic_machine=f301-fujitsu + ;; vxworks960) basic_machine=i960-wrs os=-vxworks @@ -946,13 +1217,16 @@ case $basic_machine in basic_machine=hppa1.1-winbond os=-proelf ;; - windows32) - basic_machine=i386-pc - os=-windows32-msvcrt + xbox) + basic_machine=i686-pc + os=-mingw32 ;; - xps | xps100) + xps | xps100) basic_machine=xps100-honeywell ;; + xscale-* | xscalee[bl]-*) + basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'` + ;; ymp) basic_machine=ymp-cray os=-unicos @@ -961,6 +1235,10 @@ case $basic_machine in basic_machine=z8k-unknown os=-sim ;; + z80-*-coff) + basic_machine=z80-unknown + os=-sim + ;; none) basic_machine=none-none os=-none @@ -980,6 +1258,9 @@ case $basic_machine in romp) basic_machine=romp-ibm ;; + mmix) + basic_machine=mmix-knuth + ;; rs6000) basic_machine=rs6000-ibm ;; @@ -996,16 +1277,13 @@ case $basic_machine in we32k) basic_machine=we32k-att ;; - sh3 | sh4 | sh3eb | sh4eb) + sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) basic_machine=sh-unknown ;; - sh64) - basic_machine=sh64-unknown - ;; - sparc | sparcv9 | sparcv9b) + sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) basic_machine=sparc-sun ;; - cydra) + cydra) basic_machine=cydra-cydrome ;; orion) @@ -1020,10 +1298,6 @@ case $basic_machine in pmac | pmac-mpw) basic_machine=powerpc-apple ;; - c4x*) - basic_machine=c4x-none - os=-coff - ;; *-unknown) # Make sure to match an already-canonicalized machine name. ;; @@ -1050,9 +1324,12 @@ esac if [ x"$os" != x"" ] then case $os in - # First match some system type aliases - # that might get confused with valid system types. + # First match some system type aliases + # that might get confused with valid system types. # -solaris* is a basic system type, with this one exception. + -auroraux) + os=-auroraux + ;; -solaris1 | -solaris1.*) os=`echo $os | sed -e 's|solaris1|sunos4|'` ;; @@ -1073,24 +1350,31 @@ case $os in # Each alternative MUST END IN A *, to match a version number. # -sysv* is not here because it comes later, after sysvr4. -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ - | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ - | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ + | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ + | -sym* | -kopensolaris* | -plan9* \ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ - | -aos* \ + | -aos* | -aros* \ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ - | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \ - | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ + | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ + | -bitrig* | -openbsd* | -solidbsd* \ + | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ + | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ - | -chorusos* | -chorusrdb* \ - | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ - | -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \ - | -interix* | -uwin* | -rhapsody* | -darwin* | -opened* \ + | -chorusos* | -chorusrdb* | -cegcc* \ + | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \ + | -linux-newlib* | -linux-musl* | -linux-uclibc* \ + | -uxpv* | -beos* | -mpeix* | -udk* \ + | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ - | -morphos* | -superux* | -rtmk* | -rtmk-nova*) + | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ + | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ + | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*) # Remember, each alternative MUST END IN *, to match a version number. ;; -qnx*) @@ -1102,16 +1386,21 @@ case $os in ;; esac ;; + -nto-qnx*) + ;; -nto*) - os=-nto-qnx + os=`echo $os | sed -e 's|nto|nto-qnx|'` ;; -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ - | -windows* | -osx | -abug | -netware* | -os9* | -beos* \ + | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) ;; -mac*) os=`echo $os | sed -e 's|mac|macos|'` ;; + -linux-dietlibc) + os=-linux-dietlibc + ;; -linux*) os=`echo $os | sed -e 's|linux|linux-gnu|'` ;; @@ -1124,6 +1413,9 @@ case $os in -opened*) os=-openedition ;; + -os400*) + os=-os400 + ;; -wince*) os=-wince ;; @@ -1145,6 +1437,9 @@ case $os in -atheos*) os=-atheos ;; + -syllable*) + os=-syllable + ;; -386bsd) os=-bsd ;; @@ -1155,7 +1450,7 @@ case $os in os=-rtmk-nova ;; -ns2 ) - os=-nextstep2 + os=-nextstep2 ;; -nsk*) os=-nsk @@ -1167,6 +1462,9 @@ case $os in -sinix*) os=-sysv4 ;; + -tpf*) + os=-tpf + ;; -triton*) os=-sysv3 ;; @@ -1194,8 +1492,19 @@ case $os in -xenix) os=-xenix ;; - -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) - os=-mint + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + os=-mint + ;; + -aros*) + os=-aros + ;; + -zvmoe) + os=-zvmoe + ;; + -dicos*) + os=-dicos + ;; + -nacl*) ;; -none) ;; @@ -1219,6 +1528,12 @@ else # system, and we'll never get to this point. case $basic_machine in + score-*) + os=-elf + ;; + spu-*) + os=-elf + ;; *-acorn) os=-riscix1.2 ;; @@ -1228,11 +1543,29 @@ case $basic_machine in arm*-semi) os=-aout ;; + c4x-* | tic4x-*) + os=-coff + ;; + c8051-*) + os=-elf + ;; + hexagon-*) + os=-elf + ;; + tic54x-*) + os=-coff + ;; + tic55x-*) + os=-coff + ;; + tic6x-*) + os=-coff + ;; # This must come before the *-dec entry. pdp10-*) os=-tops20 ;; - pdp11-*) + pdp11-*) os=-none ;; *-dec | vax-*) @@ -1246,19 +1579,22 @@ case $basic_machine in ;; m68000-sun) os=-sunos3 - # This also exists in the configure program, but was not the - # default. - # os=-sunos4 ;; m68*-cisco) os=-aout ;; + mep-*) + os=-elf + ;; mips*-cisco) os=-elf ;; mips*-*) os=-elf ;; + or1k-*) + os=-elf + ;; or32-*) os=-coff ;; @@ -1271,9 +1607,15 @@ case $basic_machine in *-be) os=-beos ;; + *-haiku) + os=-haiku + ;; *-ibm) os=-aix ;; + *-knuth) + os=-mmixware + ;; *-wec) os=-proelf ;; @@ -1325,19 +1667,19 @@ case $basic_machine in *-next) os=-nextstep3 ;; - *-gould) + *-gould) os=-sysv ;; - *-highlevel) + *-highlevel) os=-bsd ;; *-encore) os=-bsd ;; - *-sgi) + *-sgi) os=-irix ;; - *-siemens) + *-siemens) os=-sysv4 ;; *-masscomp) @@ -1376,7 +1718,7 @@ case $basic_machine in -sunos*) vendor=sun ;; - -aix*) + -cnk*|-aix*) vendor=ibm ;; -beos*) @@ -1406,10 +1748,16 @@ case $basic_machine in -mvs* | -opened*) vendor=ibm ;; + -os400*) + vendor=ibm + ;; -ptx*) vendor=sequent ;; - -vxsim* | -vxworks*) + -tpf*) + vendor=ibm + ;; + -vxsim* | -vxworks* | -windiss*) vendor=wrs ;; -aux*) @@ -1433,7 +1781,7 @@ case $basic_machine in esac echo $basic_machine$os -exit 0 +exit # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) diff --git a/configure.ac b/configure.ac index b9dd1ee90..84196b7a8 100644 --- a/configure.ac +++ b/configure.ac @@ -1220,7 +1220,7 @@ case $host in CXXFLAGS="$CXXFLAGS ${GLIB_CFLAGS} ${CURL_CFLAGS}" RTSP_INC= RTSP_LIB="${GLIB_LIBS} ${CURL_LIBS}" - RTSP_OBJ="src/video_capture/rtsp.o src/rtp/rtpdec_h264.o" + RTSP_OBJ="src/utils/h264_stream.o src/video_capture/rtsp.o src/rtp/rtpdec_h264.o" AC_SUBST(RTSP_LIB_TARGET, "lib/ultragrid/vidcap_rtsp.so.$video_capture_abi_version") LIB_TARGETS="$LIB_TARGETS $RTSP_LIB_TARGET" LIB_OBJS="$LIB_OBJS $RTSP_OBJ" @@ -1246,6 +1246,7 @@ AC_SUBST(RTSP_OBJ) # ------------------------------------------------------------------------------------------------- # ------------------------------------------------------------------------------------------------- # RTSP server stuff +# TODO: create pkg-config search path for liblivemedia-dev (create live555.pc file) # ------------------------------------------------------------------------------------------------- RTSP_SERVER_INC= RTSP_SERVER_LIB= @@ -1294,6 +1295,55 @@ AC_SUBST(RTSP_SERVER_INC) AC_SUBST(RTSP_SERVER_LIB) AC_SUBST(RTSP_SERVER_OBJ) +# ------------------------------------------------------------------------------------------------- +# OpenCV stuff +# ------------------------------------------------------------------------------------------------- +OPENCV_INC= +OPENCV_LIB= +OPENCV_OBJ= +opencv=no + +AC_ARG_ENABLE(opencv, + AS_HELP_STRING([--disable-opencv], [disable OpenCV support (default is auto) - resize capture filter dependency]), + [opencv_req=$enableval], + [opencv_req=auto] + ) + +case $host in + *-linux-*) + PKG_CHECK_MODULES([OPENCV], [opencv], FOUND_OPENCV_H=yes, FOUND_OPENCV_H=no) + + if test $opencv_req != no -a $FOUND_OPENCV_H = yes + then + AC_DEFINE([HAVE_OPENCV], [1], [OpenCV support - resize capture filter dependency]) + SAVED_CFLAGS=$CFLAGS + CFLAGS="$CFLAGS ${OPENCV_CFLAGS}" + SAVED_CXXFLAGS=$CXXFLAGS + CXXFLAGS="$CXXFLAGS ${OPENCV_CFLAGS}" + OPENCV_INC= + OPENCV_LIB="${OPENCV_LIBS}" + OPENCV_OBJ="src/capture_filter/resize.o src/capture_filter/resize_utils.o" + AC_SUBST(OPENCV_LIB_TARGET, "lib/ultragrid/vidcapfilter_opencv.so.$video_capture_abi_version") + LIB_TARGETS="$LIB_TARGETS $OPENCV_LIB_TARGET" + LIB_OBJS="$LIB_OBJS $OPENCV_OBJ" + opencv=yes + fi + ;; +esac + +if test $opencv_req = yes -a $opencv = no; then + AC_MSG_ERROR([OpenCV not found, may install OpenCV...?]); +fi + +LIB_MODULES="$LIB_MODULES $OPENCV_LIB" + +AC_SUBST(OPENCV_INC) +AC_SUBST(OPENCV_LIB) +AC_SUBST(OPENCV_OBJ) + + + +# ------------------------------------------------------------------------------------------------- # ------------------------------------------------------------------------------------------------- @@ -2634,6 +2684,7 @@ RESULT=\ DELTACAST ................... $deltacast DVS ......................... $dvs OpenGL ...................... $gl + OpenCV ...................... $opencv Quicktime ................... $quicktime SAGE ........................ $sage SDL ......................... $sdl diff --git a/install-sh b/install-sh index e8436696c..377bb8687 100755 --- a/install-sh +++ b/install-sh @@ -1,250 +1,527 @@ #!/bin/sh -# # install - install a program, script, or datafile -# This comes from X11R5 (mit/util/scripts/install.sh). + +scriptversion=2011-11-20.07; # UTC + +# This originates from X11R5 (mit/util/scripts/install.sh), which was +# later released in X11R6 (xc/config/util/install.sh) with the +# following copyright and license. # -# Copyright 1991 by the Massachusetts Institute of Technology +# Copyright (C) 1994 X Consortium # -# Permission to use, copy, modify, distribute, and sell this software and its -# documentation for any purpose is hereby granted without fee, provided that -# the above copyright notice appear in all copies and that both that -# copyright notice and this permission notice appear in supporting -# documentation, and that the name of M.I.T. not be used in advertising or -# publicity pertaining to distribution of the software without specific, -# written prior permission. M.I.T. makes no representations about the -# suitability of this software for any purpose. It is provided "as is" -# without express or implied warranty. +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- +# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# Except as contained in this notice, the name of the X Consortium shall not +# be used in advertising or otherwise to promote the sale, use or other deal- +# ings in this Software without prior written authorization from the X Consor- +# tium. +# +# +# FSF changes to this file are in the public domain. # # Calling this script install-sh is preferred over install.sh, to prevent -# `make' implicit rules from creating a file called install from it +# 'make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written -# from scratch. It can only install one file at a time, a restriction -# shared with many OS's install programs. +# from scratch. +nl=' +' +IFS=" "" $nl" # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. -doit="${DOITPROG-}" - - -# put in absolute paths if you don't have them in your path; or use env. vars. - -mvprog="${MVPROG-mv}" -cpprog="${CPPROG-cp}" -chmodprog="${CHMODPROG-chmod}" -chownprog="${CHOWNPROG-chown}" -chgrpprog="${CHGRPPROG-chgrp}" -stripprog="${STRIPPROG-strip}" -rmprog="${RMPROG-rm}" -mkdirprog="${MKDIRPROG-mkdir}" - -transformbasename="" -transform_arg="" -instcmd="$mvprog" -chmodcmd="$chmodprog 0755" -chowncmd="" -chgrpcmd="" -stripcmd="" -rmcmd="$rmprog -f" -mvcmd="$mvprog" -src="" -dst="" -dir_arg="" - -while [ x"$1" != x ]; do - case $1 in - -c) instcmd="$cpprog" - shift - continue;; - - -d) dir_arg=true - shift - continue;; - - -m) chmodcmd="$chmodprog $2" - shift - shift - continue;; - - -o) chowncmd="$chownprog $2" - shift - shift - continue;; - - -g) chgrpcmd="$chgrpprog $2" - shift - shift - continue;; - - -s) stripcmd="$stripprog" - shift - continue;; - - -t=*) transformarg=`echo $1 | sed 's/-t=//'` - shift - continue;; - - -b=*) transformbasename=`echo $1 | sed 's/-b=//'` - shift - continue;; - - *) if [ x"$src" = x ] - then - src=$1 - else - # this colon is to work around a 386BSD /bin/sh bug - : - dst=$1 - fi - shift - continue;; - esac -done - -if [ x"$src" = x ] -then - echo "install: no input file specified" - exit 1 +doit=${DOITPROG-} +if test -z "$doit"; then + doit_exec=exec else - true + doit_exec=$doit fi -if [ x"$dir_arg" != x ]; then - dst=$src - src="" - - if [ -d $dst ]; then - instcmd=: - else - instcmd=mkdir - fi -else +# Put in absolute file names if you don't have them in your path; +# or use environment vars. -# Waiting for this to be detected by the "$instcmd $src $dsttmp" command -# might cause directories to be created, which would be especially bad -# if $src (and thus $dsttmp) contains '*'. +chgrpprog=${CHGRPPROG-chgrp} +chmodprog=${CHMODPROG-chmod} +chownprog=${CHOWNPROG-chown} +cmpprog=${CMPPROG-cmp} +cpprog=${CPPROG-cp} +mkdirprog=${MKDIRPROG-mkdir} +mvprog=${MVPROG-mv} +rmprog=${RMPROG-rm} +stripprog=${STRIPPROG-strip} - if [ -f $src -o -d $src ] - then - true - else - echo "install: $src does not exist" - exit 1 - fi - - if [ x"$dst" = x ] - then - echo "install: no destination specified" - exit 1 - else - true - fi - -# If destination is a directory, append the input filename; if your system -# does not like double slashes in filenames, you may need to add some logic - - if [ -d $dst ] - then - dst="$dst"/`basename $src` - else - true - fi -fi - -## this sed command emulates the dirname command -dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` - -# Make sure that the destination directory exists. -# this part is taken from Noah Friedman's mkinstalldirs script - -# Skip lots of stat calls in the usual case. -if [ ! -d "$dstdir" ]; then -defaultIFS=' +posix_glob='?' +initialize_posix_glob=' + test "$posix_glob" != "?" || { + if (set -f) 2>/dev/null; then + posix_glob= + else + posix_glob=: + fi + } ' -IFS="${IFS-${defaultIFS}}" -oIFS="${IFS}" -# Some sh's can't handle IFS=/ for some reason. -IFS='%' -set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` -IFS="${oIFS}" +posix_mkdir= -pathcomp='' +# Desired mode of installed file. +mode=0755 -while [ $# -ne 0 ] ; do - pathcomp="${pathcomp}${1}" - shift +chgrpcmd= +chmodcmd=$chmodprog +chowncmd= +mvcmd=$mvprog +rmcmd="$rmprog -f" +stripcmd= - if [ ! -d "${pathcomp}" ] ; - then - $mkdirprog "${pathcomp}" - else - true - fi +src= +dst= +dir_arg= +dst_arg= - pathcomp="${pathcomp}/" +copy_on_change=false +no_target_directory= + +usage="\ +Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE + or: $0 [OPTION]... SRCFILES... DIRECTORY + or: $0 [OPTION]... -t DIRECTORY SRCFILES... + or: $0 [OPTION]... -d DIRECTORIES... + +In the 1st form, copy SRCFILE to DSTFILE. +In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. +In the 4th, create DIRECTORIES. + +Options: + --help display this help and exit. + --version display version info and exit. + + -c (ignored) + -C install only if different (preserve the last data modification time) + -d create directories instead of installing files. + -g GROUP $chgrpprog installed files to GROUP. + -m MODE $chmodprog installed files to MODE. + -o USER $chownprog installed files to USER. + -s $stripprog installed files. + -t DIRECTORY install into DIRECTORY. + -T report an error if DSTFILE is a directory. + +Environment variables override the default commands: + CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG + RMPROG STRIPPROG +" + +while test $# -ne 0; do + case $1 in + -c) ;; + + -C) copy_on_change=true;; + + -d) dir_arg=true;; + + -g) chgrpcmd="$chgrpprog $2" + shift;; + + --help) echo "$usage"; exit $?;; + + -m) mode=$2 + case $mode in + *' '* | *' '* | *' +'* | *'*'* | *'?'* | *'['*) + echo "$0: invalid mode: $mode" >&2 + exit 1;; + esac + shift;; + + -o) chowncmd="$chownprog $2" + shift;; + + -s) stripcmd=$stripprog;; + + -t) dst_arg=$2 + # Protect names problematic for 'test' and other utilities. + case $dst_arg in + -* | [=\(\)!]) dst_arg=./$dst_arg;; + esac + shift;; + + -T) no_target_directory=true;; + + --version) echo "$0 $scriptversion"; exit $?;; + + --) shift + break;; + + -*) echo "$0: invalid option: $1" >&2 + exit 1;; + + *) break;; + esac + shift done + +if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then + # When -d is used, all remaining arguments are directories to create. + # When -t is used, the destination is already specified. + # Otherwise, the last argument is the destination. Remove it from $@. + for arg + do + if test -n "$dst_arg"; then + # $@ is not empty: it contains at least $arg. + set fnord "$@" "$dst_arg" + shift # fnord + fi + shift # arg + dst_arg=$arg + # Protect names problematic for 'test' and other utilities. + case $dst_arg in + -* | [=\(\)!]) dst_arg=./$dst_arg;; + esac + done fi -if [ x"$dir_arg" != x ] -then - $doit $instcmd $dst && +if test $# -eq 0; then + if test -z "$dir_arg"; then + echo "$0: no input file specified." >&2 + exit 1 + fi + # It's OK to call 'install-sh -d' without argument. + # This can happen when creating conditional directories. + exit 0 +fi - if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && - if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && - if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && - if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi -else +if test -z "$dir_arg"; then + do_exit='(exit $ret); exit $ret' + trap "ret=129; $do_exit" 1 + trap "ret=130; $do_exit" 2 + trap "ret=141; $do_exit" 13 + trap "ret=143; $do_exit" 15 -# If we're going to rename the final executable, determine the name now. + # Set umask so as not to create temps with too-generous modes. + # However, 'strip' requires both read and write access to temps. + case $mode in + # Optimize common cases. + *644) cp_umask=133;; + *755) cp_umask=22;; - if [ x"$transformarg" = x ] - then - dstfile=`basename $dst` + *[0-7]) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw='% 200' + fi + cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; + *) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw=,u+rw + fi + cp_umask=$mode$u_plus_rw;; + esac +fi + +for src +do + # Protect names problematic for 'test' and other utilities. + case $src in + -* | [=\(\)!]) src=./$src;; + esac + + if test -n "$dir_arg"; then + dst=$src + dstdir=$dst + test -d "$dstdir" + dstdir_status=$? + else + + # Waiting for this to be detected by the "$cpprog $src $dsttmp" command + # might cause directories to be created, which would be especially bad + # if $src (and thus $dsttmp) contains '*'. + if test ! -f "$src" && test ! -d "$src"; then + echo "$0: $src does not exist." >&2 + exit 1 + fi + + if test -z "$dst_arg"; then + echo "$0: no destination specified." >&2 + exit 1 + fi + dst=$dst_arg + + # If destination is a directory, append the input filename; won't work + # if double slashes aren't ignored. + if test -d "$dst"; then + if test -n "$no_target_directory"; then + echo "$0: $dst_arg: Is a directory" >&2 + exit 1 + fi + dstdir=$dst + dst=$dstdir/`basename "$src"` + dstdir_status=0 + else + # Prefer dirname, but fall back on a substitute if dirname fails. + dstdir=` + (dirname "$dst") 2>/dev/null || + expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$dst" : 'X\(//\)[^/]' \| \ + X"$dst" : 'X\(//\)$' \| \ + X"$dst" : 'X\(/\)' \| . 2>/dev/null || + echo X"$dst" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q' + ` + + test -d "$dstdir" + dstdir_status=$? + fi + fi + + obsolete_mkdir_used=false + + if test $dstdir_status != 0; then + case $posix_mkdir in + '') + # Create intermediate dirs using mode 755 as modified by the umask. + # This is like FreeBSD 'install' as of 1997-10-28. + umask=`umask` + case $stripcmd.$umask in + # Optimize common cases. + *[2367][2367]) mkdir_umask=$umask;; + .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; + + *[0-7]) + mkdir_umask=`expr $umask + 22 \ + - $umask % 100 % 40 + $umask % 20 \ + - $umask % 10 % 4 + $umask % 2 + `;; + *) mkdir_umask=$umask,go-w;; + esac + + # With -d, create the new directory with the user-specified mode. + # Otherwise, rely on $mkdir_umask. + if test -n "$dir_arg"; then + mkdir_mode=-m$mode else - dstfile=`basename $dst $transformbasename | - sed $transformarg`$transformbasename + mkdir_mode= fi -# don't allow the sed command to completely eliminate the filename + posix_mkdir=false + case $umask in + *[123567][0-7][0-7]) + # POSIX mkdir -p sets u+wx bits regardless of umask, which + # is incompatible with FreeBSD 'install' when (umask & 300) != 0. + ;; + *) + tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ + trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 - if [ x"$dstfile" = x ] - then - dstfile=`basename $dst` + if (umask $mkdir_umask && + exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 + then + if test -z "$dir_arg" || { + # Check for POSIX incompatibilities with -m. + # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or + # other-writable bit of parent directory when it shouldn't. + # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. + ls_ld_tmpdir=`ls -ld "$tmpdir"` + case $ls_ld_tmpdir in + d????-?r-*) different_mode=700;; + d????-?--*) different_mode=755;; + *) false;; + esac && + $mkdirprog -m$different_mode -p -- "$tmpdir" && { + ls_ld_tmpdir_1=`ls -ld "$tmpdir"` + test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" + } + } + then posix_mkdir=: + fi + rmdir "$tmpdir/d" "$tmpdir" + else + # Remove any dirs left behind by ancient mkdir implementations. + rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null + fi + trap '' 0;; + esac;; + esac + + if + $posix_mkdir && ( + umask $mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" + ) + then : + else + + # The umask is ridiculous, or mkdir does not conform to POSIX, + # or it failed possibly due to a race condition. Create the + # directory the slow way, step by step, checking for races as we go. + + case $dstdir in + /*) prefix='/';; + [-=\(\)!]*) prefix='./';; + *) prefix='';; + esac + + eval "$initialize_posix_glob" + + oIFS=$IFS + IFS=/ + $posix_glob set -f + set fnord $dstdir + shift + $posix_glob set +f + IFS=$oIFS + + prefixes= + + for d + do + test X"$d" = X && continue + + prefix=$prefix$d + if test -d "$prefix"; then + prefixes= else - true + if $posix_mkdir; then + (umask=$mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break + # Don't fail if two instances are running concurrently. + test -d "$prefix" || exit 1 + else + case $prefix in + *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; + *) qprefix=$prefix;; + esac + prefixes="$prefixes '$qprefix'" + fi fi + prefix=$prefix/ + done -# Make a temp file name in the proper directory. + if test -n "$prefixes"; then + # Don't fail if two instances are running concurrently. + (umask $mkdir_umask && + eval "\$doit_exec \$mkdirprog $prefixes") || + test -d "$dstdir" || exit 1 + obsolete_mkdir_used=true + fi + fi + fi - dsttmp=$dstdir/#inst.$$# + if test -n "$dir_arg"; then + { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && + { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || + test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 + else -# Move or copy the file name to the temp name + # Make a couple of temp file names in the proper directory. + dsttmp=$dstdir/_inst.$$_ + rmtmp=$dstdir/_rm.$$_ - $doit $instcmd $src $dsttmp && + # Trap to clean up those temp files at exit. + trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 - trap "rm -f ${dsttmp}" 0 && + # Copy the file name to the temp name. + (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && -# and set any options; do chmod last to preserve setuid bits + # and set any options; do chmod last to preserve setuid bits. + # + # If any of these fail, we abort the whole thing. If we want to + # ignore errors from any of these, just make sure not to ignore + # errors from the above "$doit $cpprog $src $dsttmp" command. + # + { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && + { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && + { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && -# If any of these fail, we abort the whole thing. If we want to -# ignore errors from any of these, just make sure not to ignore -# errors from the above "$doit $instcmd $src $dsttmp" command. + # If -C, don't bother to copy if it wouldn't change the file. + if $copy_on_change && + old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && + new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && - if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && - if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && - if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && - if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && + eval "$initialize_posix_glob" && + $posix_glob set -f && + set X $old && old=:$2:$4:$5:$6 && + set X $new && new=:$2:$4:$5:$6 && + $posix_glob set +f && -# Now rename the file to the real destination. + test "$old" = "$new" && + $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 + then + rm -f "$dsttmp" + else + # Rename the file to the real destination. + $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || - $doit $rmcmd -f $dstdir/$dstfile && - $doit $mvcmd $dsttmp $dstdir/$dstfile + # The rename failed, perhaps because mv can't rename something else + # to itself, or perhaps because mv is so ancient that it does not + # support -f. + { + # Now remove or move aside any old file at destination location. + # We try this two ways since rm can't unlink itself on some + # systems and the destination file might be busy for other + # reasons. In this case, the final cleanup might fail but the new + # file should still install successfully. + { + test ! -f "$dst" || + $doit $rmcmd -f "$dst" 2>/dev/null || + { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && + { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } + } || + { echo "$0: cannot unlink or rename $dst" >&2 + (exit 1); exit 1 + } + } && -fi && + # Now rename the file to the real destination. + $doit $mvcmd "$dsttmp" "$dst" + } + fi || exit 1 + trap '' 0 + fi +done -exit 0 +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/missing b/missing index e7ef83a1c..cdea51493 100755 --- a/missing +++ b/missing @@ -1,11 +1,10 @@ #! /bin/sh -# Common stub for a few missing GNU programs while installing. +# Common wrapper for a few potentially missing GNU programs. -scriptversion=2003-09-02.23 +scriptversion=2012-06-26.16; # UTC -# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003 -# Free Software Foundation, Inc. -# Originally by Fran,cois Pinard , 1996. +# Copyright (C) 1996-2013 Free Software Foundation, Inc. +# Originally written by Fran,cois Pinard , 1996. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -18,9 +17,7 @@ scriptversion=2003-09-02.23 # GNU General Public License for more details. # You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA -# 02111-1307, USA. +# along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a @@ -28,333 +25,191 @@ scriptversion=2003-09-02.23 # the same distribution terms that you use for the rest of that program. if test $# -eq 0; then - echo 1>&2 "Try \`$0 --help' for more information" + echo 1>&2 "Try '$0 --help' for more information" exit 1 fi -run=: +case $1 in -# In the cases where this matters, `missing' is being run in the -# srcdir already. -if test -f configure.ac; then - configure_ac=configure.ac -else - configure_ac=configure.in -fi + --is-lightweight) + # Used by our autoconf macros to check whether the available missing + # script is modern enough. + exit 0 + ;; -msg="missing on your system" - -case "$1" in ---run) - # Try to run requested program, and just exit if it succeeds. - run= - shift - "$@" && exit 0 - # Exit code 63 means version mismatch. This often happens - # when the user try to use an ancient version of a tool on - # a file that requires a minimum version. In this case we - # we should proceed has if the program had been absent, or - # if --run hadn't been passed. - if test $? = 63; then - run=: - msg="probably too old" - fi - ;; -esac - -# If it does not exist, or fails to run (possibly an outdated version), -# try to emulate it. -case "$1" in + --run) + # Back-compat with the calling convention used by older automake. + shift + ;; -h|--h|--he|--hel|--help) echo "\ $0 [OPTION]... PROGRAM [ARGUMENT]... -Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an -error status if there is no known handling for PROGRAM. +Run 'PROGRAM [ARGUMENT]...', returning a proper advice when this fails due +to PROGRAM being missing or too old. Options: -h, --help display this help and exit -v, --version output version information and exit - --run try to run the given command, and emulate it if it fails Supported PROGRAM values: - aclocal touch file \`aclocal.m4' - autoconf touch file \`configure' - autoheader touch file \`config.h.in' - automake touch all \`Makefile.in' files - bison create \`y.tab.[ch]', if possible, from existing .[ch] - flex create \`lex.yy.c', if possible, from existing .c - help2man touch the output file - lex create \`lex.yy.c', if possible, from existing .c - makeinfo touch the output file - tar try tar, gnutar, gtar, then tar without non-portable flags - yacc create \`y.tab.[ch]', if possible, from existing .[ch] + aclocal autoconf autoheader autom4te automake makeinfo + bison yacc flex lex help2man + +Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and +'g' are ignored when checking the name. Send bug reports to ." + exit $? ;; -v|--v|--ve|--ver|--vers|--versi|--versio|--version) echo "missing $scriptversion (GNU Automake)" + exit $? ;; -*) - echo 1>&2 "$0: Unknown \`$1' option" - echo 1>&2 "Try \`$0 --help' for more information" + echo 1>&2 "$0: unknown '$1' option" + echo 1>&2 "Try '$0 --help' for more information" exit 1 ;; - aclocal*) - if test -z "$run" && ($1 --version) > /dev/null 2>&1; then - # We have it, but it failed. - exit 1 - fi - - echo 1>&2 "\ -WARNING: \`$1' is $msg. You should only need it if - you modified \`acinclude.m4' or \`${configure_ac}'. You might want - to install the \`Automake' and \`Perl' packages. Grab them from - any GNU archive site." - touch aclocal.m4 - ;; - - autoconf) - if test -z "$run" && ($1 --version) > /dev/null 2>&1; then - # We have it, but it failed. - exit 1 - fi - - echo 1>&2 "\ -WARNING: \`$1' is $msg. You should only need it if - you modified \`${configure_ac}'. You might want to install the - \`Autoconf' and \`GNU m4' packages. Grab them from any GNU - archive site." - touch configure - ;; - - autoheader) - if test -z "$run" && ($1 --version) > /dev/null 2>&1; then - # We have it, but it failed. - exit 1 - fi - - echo 1>&2 "\ -WARNING: \`$1' is $msg. You should only need it if - you modified \`acconfig.h' or \`${configure_ac}'. You might want - to install the \`Autoconf' and \`GNU m4' packages. Grab them - from any GNU archive site." - files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}` - test -z "$files" && files="config.h" - touch_files= - for f in $files; do - case "$f" in - *:*) touch_files="$touch_files "`echo "$f" | - sed -e 's/^[^:]*://' -e 's/:.*//'`;; - *) touch_files="$touch_files $f.in";; - esac - done - touch $touch_files - ;; - - automake*) - if test -z "$run" && ($1 --version) > /dev/null 2>&1; then - # We have it, but it failed. - exit 1 - fi - - echo 1>&2 "\ -WARNING: \`$1' is $msg. You should only need it if - you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'. - You might want to install the \`Automake' and \`Perl' packages. - Grab them from any GNU archive site." - find . -type f -name Makefile.am -print | - sed 's/\.am$/.in/' | - while read f; do touch "$f"; done - ;; - - autom4te) - if test -z "$run" && ($1 --version) > /dev/null 2>&1; then - # We have it, but it failed. - exit 1 - fi - - echo 1>&2 "\ -WARNING: \`$1' is needed, but is $msg. - You might have modified some files without having the - proper tools for further handling them. - You can get \`$1' as part of \`Autoconf' from any GNU - archive site." - - file=`echo "$*" | sed -n 's/.*--output[ =]*\([^ ]*\).*/\1/p'` - test -z "$file" && file=`echo "$*" | sed -n 's/.*-o[ ]*\([^ ]*\).*/\1/p'` - if test -f "$file"; then - touch $file - else - test -z "$file" || exec >$file - echo "#! /bin/sh" - echo "# Created by GNU Automake missing as a replacement of" - echo "# $ $@" - echo "exit 0" - chmod +x $file - exit 1 - fi - ;; - - bison|yacc) - echo 1>&2 "\ -WARNING: \`$1' $msg. You should only need it if - you modified a \`.y' file. You may need the \`Bison' package - in order for those modifications to take effect. You can get - \`Bison' from any GNU archive site." - rm -f y.tab.c y.tab.h - if [ $# -ne 1 ]; then - eval LASTARG="\${$#}" - case "$LASTARG" in - *.y) - SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` - if [ -f "$SRCFILE" ]; then - cp "$SRCFILE" y.tab.c - fi - SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` - if [ -f "$SRCFILE" ]; then - cp "$SRCFILE" y.tab.h - fi - ;; - esac - fi - if [ ! -f y.tab.h ]; then - echo >y.tab.h - fi - if [ ! -f y.tab.c ]; then - echo 'main() { return 0; }' >y.tab.c - fi - ;; - - lex|flex) - echo 1>&2 "\ -WARNING: \`$1' is $msg. You should only need it if - you modified a \`.l' file. You may need the \`Flex' package - in order for those modifications to take effect. You can get - \`Flex' from any GNU archive site." - rm -f lex.yy.c - if [ $# -ne 1 ]; then - eval LASTARG="\${$#}" - case "$LASTARG" in - *.l) - SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` - if [ -f "$SRCFILE" ]; then - cp "$SRCFILE" lex.yy.c - fi - ;; - esac - fi - if [ ! -f lex.yy.c ]; then - echo 'main() { return 0; }' >lex.yy.c - fi - ;; - - help2man) - if test -z "$run" && ($1 --version) > /dev/null 2>&1; then - # We have it, but it failed. - exit 1 - fi - - echo 1>&2 "\ -WARNING: \`$1' is $msg. You should only need it if - you modified a dependency of a manual page. You may need the - \`Help2man' package in order for those modifications to take - effect. You can get \`Help2man' from any GNU archive site." - - file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` - if test -z "$file"; then - file=`echo "$*" | sed -n 's/.*--output=\([^ ]*\).*/\1/p'` - fi - if [ -f "$file" ]; then - touch $file - else - test -z "$file" || exec >$file - echo ".ab help2man is required to generate this page" - exit 1 - fi - ;; - - makeinfo) - if test -z "$run" && (makeinfo --version) > /dev/null 2>&1; then - # We have makeinfo, but it failed. - exit 1 - fi - - echo 1>&2 "\ -WARNING: \`$1' is $msg. You should only need it if - you modified a \`.texi' or \`.texinfo' file, or any other file - indirectly affecting the aspect of the manual. The spurious - call might also be the consequence of using a buggy \`make' (AIX, - DU, IRIX). You might want to install the \`Texinfo' package or - the \`GNU make' package. Grab either from any GNU archive site." - file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` - if test -z "$file"; then - file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` - file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file` - fi - touch $file - ;; - - tar) - shift - if test -n "$run"; then - echo 1>&2 "ERROR: \`tar' requires --run" - exit 1 - fi - - # We have already tried tar in the generic part. - # Look for gnutar/gtar before invocation to avoid ugly error - # messages. - if (gnutar --version > /dev/null 2>&1); then - gnutar "$@" && exit 0 - fi - if (gtar --version > /dev/null 2>&1); then - gtar "$@" && exit 0 - fi - firstarg="$1" - if shift; then - case "$firstarg" in - *o*) - firstarg=`echo "$firstarg" | sed s/o//` - tar "$firstarg" "$@" && exit 0 - ;; - esac - case "$firstarg" in - *h*) - firstarg=`echo "$firstarg" | sed s/h//` - tar "$firstarg" "$@" && exit 0 - ;; - esac - fi - - echo 1>&2 "\ -WARNING: I can't seem to be able to run \`tar' with the given arguments. - You may want to install GNU tar or Free paxutils, or check the - command line arguments." - exit 1 - ;; - - *) - echo 1>&2 "\ -WARNING: \`$1' is needed, and is $msg. - You might have modified some files without having the - proper tools for further handling them. Check the \`README' file, - it often tells you about the needed prerequisites for installing - this package. You may also peek at any GNU archive site, in case - some other package would contain this missing \`$1' program." - exit 1 - ;; esac -exit 0 +# Run the given program, remember its exit status. +"$@"; st=$? + +# If it succeeded, we are done. +test $st -eq 0 && exit 0 + +# Also exit now if we it failed (or wasn't found), and '--version' was +# passed; such an option is passed most likely to detect whether the +# program is present and works. +case $2 in --version|--help) exit $st;; esac + +# Exit code 63 means version mismatch. This often happens when the user +# tries to use an ancient version of a tool on a file that requires a +# minimum version. +if test $st -eq 63; then + msg="probably too old" +elif test $st -eq 127; then + # Program was missing. + msg="missing on your system" +else + # Program was found and executed, but failed. Give up. + exit $st +fi + +perl_URL=http://www.perl.org/ +flex_URL=http://flex.sourceforge.net/ +gnu_software_URL=http://www.gnu.org/software + +program_details () +{ + case $1 in + aclocal|automake) + echo "The '$1' program is part of the GNU Automake package:" + echo "<$gnu_software_URL/automake>" + echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:" + echo "<$gnu_software_URL/autoconf>" + echo "<$gnu_software_URL/m4/>" + echo "<$perl_URL>" + ;; + autoconf|autom4te|autoheader) + echo "The '$1' program is part of the GNU Autoconf package:" + echo "<$gnu_software_URL/autoconf/>" + echo "It also requires GNU m4 and Perl in order to run:" + echo "<$gnu_software_URL/m4/>" + echo "<$perl_URL>" + ;; + esac +} + +give_advice () +{ + # Normalize program name to check for. + normalized_program=`echo "$1" | sed ' + s/^gnu-//; t + s/^gnu//; t + s/^g//; t'` + + printf '%s\n' "'$1' is $msg." + + configure_deps="'configure.ac' or m4 files included by 'configure.ac'" + case $normalized_program in + autoconf*) + echo "You should only need it if you modified 'configure.ac'," + echo "or m4 files included by it." + program_details 'autoconf' + ;; + autoheader*) + echo "You should only need it if you modified 'acconfig.h' or" + echo "$configure_deps." + program_details 'autoheader' + ;; + automake*) + echo "You should only need it if you modified 'Makefile.am' or" + echo "$configure_deps." + program_details 'automake' + ;; + aclocal*) + echo "You should only need it if you modified 'acinclude.m4' or" + echo "$configure_deps." + program_details 'aclocal' + ;; + autom4te*) + echo "You might have modified some maintainer files that require" + echo "the 'automa4te' program to be rebuilt." + program_details 'autom4te' + ;; + bison*|yacc*) + echo "You should only need it if you modified a '.y' file." + echo "You may want to install the GNU Bison package:" + echo "<$gnu_software_URL/bison/>" + ;; + lex*|flex*) + echo "You should only need it if you modified a '.l' file." + echo "You may want to install the Fast Lexical Analyzer package:" + echo "<$flex_URL>" + ;; + help2man*) + echo "You should only need it if you modified a dependency" \ + "of a man page." + echo "You may want to install the GNU Help2man package:" + echo "<$gnu_software_URL/help2man/>" + ;; + makeinfo*) + echo "You should only need it if you modified a '.texi' file, or" + echo "any other file indirectly affecting the aspect of the manual." + echo "You might want to install the Texinfo package:" + echo "<$gnu_software_URL/texinfo/>" + echo "The spurious makeinfo call might also be the consequence of" + echo "using a buggy 'make' (AIX, DU, IRIX), in which case you might" + echo "want to install GNU make:" + echo "<$gnu_software_URL/make/>" + ;; + *) + echo "You might have modified some files without having the proper" + echo "tools for further handling them. Check the 'README' file, it" + echo "often tells you about the needed prerequisites for installing" + echo "this package. You may also peek at any GNU archive site, in" + echo "case some other package contains this missing '$1' program." + ;; + esac +} + +give_advice "$1" | sed -e '1s/^/WARNING: /' \ + -e '2,$s/^/ /' >&2 + +# Propagate the correct exit status (expected to be 127 for a program +# not found, 63 for a program that failed due to version mismatch). +exit $st # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" -# time-stamp-end: "$" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" # End: diff --git a/src/audio/audio.c b/src/audio/audio.c index 6077ee1bc..946c48959 100644 --- a/src/audio/audio.c +++ b/src/audio/audio.c @@ -543,10 +543,56 @@ static void *audio_receiver_thread(void *arg) } pdb_iter_done(&it); }else if(s->receiver == NET_STANDARD){ - //TODO receive mulaw standard RTP (decode frame mulaw callback) + //TODO now expecting to receive mulaw standard RTP (decode frame mulaw callback) , next steps, to be dynamic... + gettimeofday(&curr_time, NULL); + ts = tv_diff(curr_time, s->start_time) * 90000; + rtp_update(s->audio_network_device, curr_time); + rtp_send_ctrl(s->audio_network_device, ts, 0, curr_time); + timeout.tv_sec = 0; + timeout.tv_usec = 999999 / 59.94; /* audio goes almost always at the same rate + as video frames */ + rtp_recv_r(s->audio_network_device, &timeout, ts); + pdb_iter_t it; + cp = pdb_iter_init(s->audio_participants, &it); + while (cp != NULL) { + if (audio_pbuf_decode(cp->playout_buffer, curr_time, decode_audio_frame_mulaw, &pbuf_data)) { + bool failed = false; + if(s->echo_state) { +#ifdef HAVE_SPEEX +echo_play(s->echo_state, &pbuf_data.buffer); +#endif + } + struct audio_desc curr_desc; + curr_desc = audio_desc_from_audio_frame(&pbuf_data.buffer); + if(!audio_desc_eq(device_desc, curr_desc)) { + if(audio_reconfigure(s, curr_desc.bps * 8, + curr_desc.ch_count, + curr_desc.sample_rate) != TRUE) { + fprintf(stderr, "Audio reconfiguration failed!"); + failed = true; + } + else { + fprintf(stderr, "Audio reconfiguration succeeded."); + device_desc = curr_desc; + rtp_flush_recv_buf(s->audio_network_device); + } + fprintf(stderr, " (%d channels, %d bps, %d Hz)\n", + curr_desc.ch_count, + curr_desc.bps, curr_desc.sample_rate); + + } + + if(!failed) + audio_playback_put_frame(s->audio_playback_device, &pbuf_data.buffer); + } + + pbuf_remove(cp->playout_buffer, curr_time); + cp = pdb_iter_next(&it); + } + pdb_iter_done(&it); }else { /* NET_JACK */ #ifdef HAVE_JACK_TRANS decoded = jack_receive(s->jack_connection, &pbuf_data); @@ -752,7 +798,6 @@ static void *audio_sender_thread(void *arg) } } }else if(s->sender == NET_STANDARD){ - //TODO audio_tx_send_mulaw // RESAMPLE resample(&resample_state, buffer); // COMPRESS diff --git a/src/capture_filter.c b/src/capture_filter.c index bb24174fe..c014f2b88 100644 --- a/src/capture_filter.c +++ b/src/capture_filter.c @@ -62,9 +62,15 @@ #include "capture_filter/logo.h" #include "capture_filter/none.h" #include "capture_filter/scale.h" +#ifdef HAVE_OPENCV +#include "capture_filter/resize.h" +#endif static struct capture_filter_info *capture_filters[] = { &capture_filter_blank, +#ifdef HAVE_OPENCV + &capture_filter_resize, +#endif &capture_filter_every, &capture_filter_logo, &capture_filter_none, diff --git a/src/capture_filter/resize.cpp b/src/capture_filter/resize.cpp new file mode 100644 index 000000000..50eff5334 --- /dev/null +++ b/src/capture_filter/resize.cpp @@ -0,0 +1,190 @@ +/* + * FILE: capture_filter/resize.cpp + * AUTHORS: Gerard Castillo + * Marc Palau + * + * Copyright (c) 2005-2010 Fundació i2CAT, Internet I Innovació Digital a Catalunya + * + * Redistribution and use in source and binary forms, with or without + * modification, is 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. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * + * This product includes software developed by the Fundació i2CAT, + * Internet I Innovació Digital a Catalunya. This product also includes + * software developed by CESNET z.s.p.o. + * + * 4. Neither the name of the University nor of the Institute may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESSED 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 AUTHORS OR CONTRIBUTORS 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. + * + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#include "config_unix.h" +#include "config_win32.h" +#endif /* HAVE_CONFIG_H */ + +#include "capture_filter/resize_utils.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#include "capture_filter.h" + +#include "debug.h" + +#include "video.h" +#include "video_codec.h" + +#define MAX_TILES 16 + +struct module; + +static int init(struct module *parent, const char *cfg, void **state); +static void done(void *state); +static struct video_frame *filter(void *state, struct video_frame *in); + +struct state_resize { + int num; + int orig_width; + int orig_height; + int denom; + double scale_factor; + int reinit; + struct video_frame *frame; +}; + +static void usage() { + printf("\nDownscaling by scale factor:\n\n"); + printf("resize usage:\n"); + printf("\tresize:numerator/denominator\n\n"); + printf("Downscaling example: resize:1/2 - downscale input frame size by scale factor of 2\n"); +} + +static int init(struct module *parent, const char *cfg, void **state) +{ + UNUSED(parent); + + int n; + int denom = 1;; + if(cfg) { + if(strcasecmp(cfg, "help") == 0) { + usage(); + return 1; + } + n = atoi(cfg); + if(strchr(cfg, '/')) { + denom = atoi(strchr(cfg, '/') + 1); + } + } else { + usage(); + return -1; + } + + if(n <= 0 || denom <= 0){ + printf("\n[RESIZE ERROR] numerator and denominator resize factors must be greater than zero!\n"); + usage(); + return -1; + } + if(n/denom > 1.0){ + printf("\n[RESIZE ERROR] numerator and denominator resize factors must be lower than 1 (only downscaling is supported)\n"); + usage(); + return -1; + } + + struct state_resize *s = (state_resize*) calloc(1, sizeof(struct state_resize)); + s->reinit = 1; + s->num = n; + s->denom = denom; + + *state = s; + return 0; +} + +static void done(void *state) +{ + struct state_resize *s = (state_resize*) state; + + vf_free(s->frame); + free(state); +} + + + +static struct video_frame *filter(void *state, struct video_frame *in) +{ + struct state_resize *s = (state_resize*) state; + unsigned int i; + int res = 0; + assert(in->tile_count <= MAX_TILES); + + if(s->reinit==1){ + struct video_desc desc = video_desc_from_frame(in); + s->frame = vf_alloc_desc_data(desc); + } + + for(i=0; iframe->tile_count;i++){ + if(s->reinit==1){ + //TODO: all tiles could have different sizes and other color specs different than UYVY and RGB + s->orig_width = s->frame->tiles[i].width; + s->orig_height = s->frame->tiles[i].height; + s->frame->tiles[i].width *= s->num; + s->frame->tiles[i].width /= s->denom; + s->frame->tiles[i].height *= s->num; + s->frame->tiles[i].height /= s->denom; + s->frame->color_spec = RGB; + s->scale_factor = (double)s->num/s->denom; + s->reinit = 0; + if(i==0) printf("[resize filter] resizing from %dx%d to %dx%d\n", in->tiles[i].width, in->tiles[i].height, s->frame->tiles[i].width, s->frame->tiles[i].height); + } + + res = resize_frame(in->tiles[i].data, in->color_spec, s->frame->tiles[i].data, &s->frame->tiles[i].data_len, s->orig_width, s->orig_height, s->scale_factor); + + if(res!=0){ + error_msg("\n[RESIZE ERROR] Unable to resize with scale factor configured [%d/%d] in tile number %d\n", s->num, s->denom, i); + error_msg("\t\t No scale factor applied at all. No frame returns...\n"); + return NULL; + }else{ + s->frame->color_spec = RGB; + s->frame->codec = RGB; + } + } + + return s->frame; +} + +struct capture_filter_info capture_filter_resize = { + "resize", + init, + done, + filter, +}; + +#ifdef __cplusplus +} +#endif diff --git a/src/capture_filter/resize.h b/src/capture_filter/resize.h new file mode 100644 index 000000000..bd4eb9213 --- /dev/null +++ b/src/capture_filter/resize.h @@ -0,0 +1,57 @@ +/* + * FILE: capture_filter/resize.h + * AUTHORS: Gerard Castillo + * Marc Palau + * + * Copyright (c) 2005-2010 Fundació i2CAT, Internet I Innovació Digital a Catalunya + * + * Redistribution and use in source and binary forms, with or without + * modification, is 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. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * + * This product includes software developed by the Fundació i2CAT, + * Internet I Innovació Digital a Catalunya. This product also includes + * software developed by CESNET z.s.p.o. + * + * 4. Neither the name of the University nor of the Institute may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESSED 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 AUTHORS OR CONTRIBUTORS 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. + * + */ + +#ifndef CAPTURE_FILTER_RESIZE_H_ +#define CAPTURE_FILTER_RESIZE_H_ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#include "config_win32.h" +#include "config_unix.h" +#endif // HAVE_CONFIG_H + +struct capture_filter_info; +extern struct capture_filter_info capture_filter_resize; + +#endif // CAPTURE_FILTER_RESIZE_H_ diff --git a/src/capture_filter/resize_utils.cpp b/src/capture_filter/resize_utils.cpp new file mode 100644 index 000000000..a35885891 --- /dev/null +++ b/src/capture_filter/resize_utils.cpp @@ -0,0 +1,77 @@ +/* + * FILE: capture_filter/resize_utils.cpp + * AUTHORS: Gerard Castillo + * Marc Palau + * + * Copyright (c) 2005-2010 Fundació i2CAT, Internet I Innovació Digital a Catalunya + * + * Redistribution and use in source and binary forms, with or without + * modification, is 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. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * + * This product includes software developed by the Fundació i2CAT, + * Internet I Innovació Digital a Catalunya. This product also includes + * software developed by CESNET z.s.p.o. + * + * 4. Neither the name of the University nor of the Institute may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESSED 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 AUTHORS OR CONTRIBUTORS 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. + * + */ + +#include "capture_filter/resize_utils.h" + +using namespace cv; + +int resize_frame(char *indata, codec_t in_color, char *outdata, unsigned int *data_len, unsigned int width, unsigned int height, double scale_factor){ + assert(in_color == UYVY || in_color == RGB); + + int res = 0; + Mat out, in, rgb; + + if (indata == NULL || outdata == NULL || data_len == NULL) { + return 1; + } + + switch(in_color){ + case UYVY: + in.create(height, width, CV_8UC2); + in.data = (uchar*)indata; + cvtColor(in, rgb, CV_YUV2RGB_UYVY); + resize(rgb, out, Size(0,0), scale_factor, scale_factor, INTER_LINEAR); + break; + case RGB: + in.create(height, width, CV_8UC3); + in.data = (uchar*)indata; + resize(in, out, Size(0,0), scale_factor, scale_factor, INTER_LINEAR); + break; + } + + *data_len = out.step * out.rows * sizeof(char); + memcpy(outdata,out.data,*data_len); + + return res; +} diff --git a/src/capture_filter/resize_utils.h b/src/capture_filter/resize_utils.h new file mode 100644 index 000000000..b77629ea3 --- /dev/null +++ b/src/capture_filter/resize_utils.h @@ -0,0 +1,60 @@ +/* + * FILE: capture_filter/resize_utils.c + * AUTHORS: Gerard Castillo + * Marc Palau + * + * Copyright (c) 2005-2010 Fundació i2CAT, Internet I Innovació Digital a Catalunya + * + * Redistribution and use in source and binary forms, with or without + * modification, is 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. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * + * This product includes software developed by the Fundació i2CAT, + * Internet I Innovació Digital a Catalunya. This product also includes + * software developed by CESNET z.s.p.o. + * + * 4. Neither the name of the University nor of the Institute may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESSED 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 AUTHORS OR CONTRIBUTORS 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. + * + */ + +#ifndef RESIZE_UTILS_H_ +#define RESIZE_UTILS_H_ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#include "config_unix.h" +#include "config_win32.h" +#endif + +#include +#include +#include "types.h" + +int resize_frame(char *indata, codec_t in_color, char *outdata, unsigned int *data_len, unsigned int width, unsigned int height, double scale_factor); + +#endif// RESIZE_UTILS_H_ diff --git a/src/main.cpp b/src/main.cpp index 29098dc06..c181d028c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -96,14 +96,14 @@ #include #endif -#define EXIT_FAIL_USAGE 1 -#define EXIT_FAIL_UI 2 -#define EXIT_FAIL_DISPLAY 3 -#define EXIT_FAIL_CAPTURE 4 -#define EXIT_FAIL_NETWORK 5 -#define EXIT_FAIL_TRANSMIT 6 -#define EXIT_FAIL_COMPRESS 7 -#define EXIT_FAIL_DECODER 8 +#define EXIT_FAIL_USAGE 1 +#define EXIT_FAIL_UI 2 +#define EXIT_FAIL_DISPLAY 3 +#define EXIT_FAIL_CAPTURE 4 +#define EXIT_FAIL_NETWORK 5 +#define EXIT_FAIL_TRANSMIT 6 +#define EXIT_FAIL_COMPRESS 7 +#define EXIT_FAIL_DECODER 8 #define PORT_BASE 5004 #define PORT_AUDIO 5006 @@ -433,6 +433,7 @@ int main(int argc, char *argv[]) const char *requested_audio_fec = DEFAULT_AUDIO_FEC; char *audio_channel_map = NULL; const char *audio_scale = "mixauto"; + rtsp_serv_t* rtsp_server = NULL; bool isStd = FALSE; int recv_port_number = PORT_BASE; int send_port_number = PORT_BASE; @@ -460,8 +461,8 @@ int main(int argc, char *argv[]) pthread_t receiver_thread_id, capture_thread_id; - bool receiver_thread_started = false, - capture_thread_started = false; + bool receiver_thread_started = false, + capture_thread_started = false; unsigned display_flags = 0; int ret; struct vidcap_params *audio_cap_dev; @@ -551,11 +552,11 @@ int main(int argc, char *argv[]) return 0; } requested_display = optarg; - if(strchr(optarg, ':')) { - char *delim = strchr(optarg, ':'); - *delim = '\0'; - display_cfg = delim + 1; - } + if(strchr(optarg, ':')) { + char *delim = strchr(optarg, ':'); + *delim = '\0'; + display_cfg = delim + 1; + } break; case 't': if (!strcmp(optarg, "help")) { @@ -633,9 +634,9 @@ int main(int argc, char *argv[]) requested_video_fec = optarg; } break; - case 'h': - usage(); - return 0; + case 'h': + usage(); + return 0; case 'P': if(strchr(optarg, ':')) { char *save_ptr = NULL; @@ -825,17 +826,17 @@ int main(int argc, char *argv[]) } #ifdef WIN32 - WSADATA wsaData; - int err = WSAStartup(MAKEWORD(2, 2), &wsaData); - if(err != 0) { - fprintf(stderr, "WSAStartup failed with error %d.", err); - return EXIT_FAILURE; - } - if(LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2) { - fprintf(stderr, "Counld not found usable version of Winsock.\n"); - WSACleanup(); - return EXIT_FAILURE; - } + WSADATA wsaData; + int err = WSAStartup(MAKEWORD(2, 2), &wsaData); + if(err != 0) { + fprintf(stderr, "WSAStartup failed with error %d.", err); + return EXIT_FAILURE; + } + if(LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2) { + fprintf(stderr, "Counld not found usable version of Winsock.\n"); + WSACleanup(); + return EXIT_FAILURE; + } #endif if(control_init(control_port, &control, &root_mod) != 0) { @@ -951,10 +952,11 @@ int main(int argc, char *argv[]) display_device, requested_mtu, argc, argv); }else if (video_protocol == H264_STD) { - uint8_t avType; - if(strcmp("none", vidcap_params_get_driver(vidcap_params_head)) != 0 && (strcmp("none",audio_send) != 0)) avType = 0; //AVStream - else if((strcmp("none",audio_send) != 0)) avType = 2; //AStream - else avType = 1; //VStream + rtps_types_t avType; + if(strcmp("none", vidcap_params_get_driver(vidcap_params_head)) != 0 && (strcmp("none",audio_send) != 0)) avType = avStdDyn; //AVStream + else if((strcmp("none",audio_send) != 0)) avType = audioPCMUdyn; //AStream + else if(strcmp("none", vidcap_params_get_driver(vidcap_params_head))) avType = videoH264; //VStream + else printf("[RTSP SERVER CHECK] no stream type... check capture devices input...\n"); uv->state_video_rxtx = new h264_rtp_video_rxtx(&root_mod, video_exporter, requested_compression, requested_encryption, @@ -971,7 +973,6 @@ int main(int argc, char *argv[]) } else { // SAGE uv->state_video_rxtx = new sage_video_rxtx(&root_mod, video_exporter, requested_compression, requested_receiver, sage_opts); - } if(rxtx_mode & MODE_RECEIVER) { @@ -1057,6 +1058,10 @@ cleanup: vidcap_params_head = next; } +#ifdef HAVE_RTSP_SERVER + if(rtsp_server) c_stop_server(rtsp_server); +#endif + module_done(&root_mod); free(uv); @@ -1065,7 +1070,7 @@ cleanup: #endif #ifdef WIN32 - WSACleanup(); + WSACleanup(); #endif printf("Exit\n"); diff --git a/src/rtp/audio_decoders.c b/src/rtp/audio_decoders.c index d897ab1ef..8b418cf4f 100644 --- a/src/rtp/audio_decoders.c +++ b/src/rtp/audio_decoders.c @@ -569,4 +569,108 @@ int decode_audio_frame(struct coded_data *cdata, void *data) return TRUE; } +/* + * Second version that uses external audio configuration, + * now it uses a struct state_audio_decoder instead an audio_frame2. + * It does multi-channel handling. + */ +int decode_audio_frame_mulaw(struct coded_data *cdata, void *data) +{ + struct pbuf_audio_data *s = (struct pbuf_audio_data *) data; + struct state_audio_decoder *audio = s->decoder; + + //struct state_audio_decoder *audio = (struct state_audio_decoder *)data; + + if(!cdata) return false; + + // Reconfiguration. + if (audio->received_frame->bps != audio->saved_desc.bps || + audio->received_frame->sample_rate != audio->saved_desc.sample_rate || + audio->received_frame->ch_count != audio->saved_desc.ch_count || + audio->received_frame->codec != audio->saved_desc.codec) + { + audio_frame2_allocate(audio->received_frame, audio->saved_desc.ch_count, audio->saved_desc.sample_rate * audio->saved_desc.bps); + audio->received_frame->bps = audio->saved_desc.bps; + audio->received_frame->sample_rate = audio->saved_desc.sample_rate; + audio->received_frame->ch_count = audio->saved_desc.ch_count; + audio->received_frame->codec = audio->saved_desc.codec; + } + + // Initial setup + for (int ch = 0 ; ch < audio->received_frame->ch_count ; ch ++) { + audio->received_frame->data_len[ch] = 0; + } + + // Check-if-there-is-only-one-channel optimization. + if (audio->received_frame->ch_count == 1) { + char *to = audio->received_frame->data[0]; + + while (cdata != NULL) { + // Get the data to copy into the received_frame. + char *from = cdata->data->data; + + // See if the data fits. + if (cdata->data->data_len <= (int)(audio->received_frame->max_size - audio->received_frame->data_len[0])) { + // Copy the data + memcpy(to, from, cdata->data->data_len); + // Update the pointer and the counter. + to += cdata->data->data_len; + audio->received_frame->data_len[0] += cdata->data->data_len; + } else { + // Filled it out, exit now. + return true; + } + + cdata = cdata->nxt; + } + } else { // Multi-channel case. + + /* + * Unoptimized version of the multi-channel handling. + * TODO: Optimize it! It's a matrix transpose. + * Take a look at http://stackoverflow.com/questions/1777901/array-interleaving-problem + */ + + char *to; + int bytes_copied = 0; + + while (cdata != NULL) { + // Check that the amount of data on cdata->data->data is congruent with 0 modulus audio->received_frame->ch_count. + if (cdata->data->data_len % audio->received_frame->ch_count != 0) { + // printf something? + return false; + } + + // If there is space on the current audio_frame2 buffer. + if ((cdata->data->data_len / audio->received_frame->ch_count) <= (int)(audio->received_frame->max_size - bytes_copied)) { + char *from = cdata->data->data; + + // For each group of samples. + for (int g = 0 ; g < (cdata->data->data_len / audio->received_frame->ch_count) ; g++) { + // Iterate throught each channel. + for (int ch = 0 ; ch < audio->received_frame->ch_count ; ch ++) { + // Copy the current sample from the RTP packet to the audio_frame2. + to = audio->received_frame->data[ch]; + to += bytes_copied; + + memcpy(to, from, audio->received_frame->bps); + + from += audio->received_frame->bps; + audio->received_frame->data_len[ch] += audio->received_frame->bps; + } + + bytes_copied += audio->received_frame->bps; + } + } else { + // Filled audio_frame2 out, exit now. + return true; + } + + cdata = cdata->nxt; + } + + } + + return true; +} diff --git a/src/rtp/audio_decoders.h b/src/rtp/audio_decoders.h index faa99e5b7..a1e69b431 100644 --- a/src/rtp/audio_decoders.h +++ b/src/rtp/audio_decoders.h @@ -54,6 +54,7 @@ struct coded_data; int decode_audio_frame(struct coded_data *cdata, void *data); +int decode_audio_frame_mulaw(struct coded_data *cdata, void *data); void *audio_decoder_init(char *audio_channel_map, const char *audio_scale, const char *encryption); void audio_decoder_destroy(void *state); diff --git a/src/rtp/pbuf.c b/src/rtp/pbuf.c index 1f0ce4019..46878b016 100644 --- a/src/rtp/pbuf.c +++ b/src/rtp/pbuf.c @@ -96,6 +96,7 @@ struct pbuf { uint32_t last_display_ts; }; +static void free_cdata(struct coded_data *head); static int frame_complete(struct pbuf_node *frame); /*********************************************************************************/ @@ -173,31 +174,60 @@ struct pbuf *pbuf_init(void) static void add_coded_unit(struct pbuf_node *node, rtp_packet * pkt) { - /* Add "pkt" to the frame represented by "node". The "node" has */ - /* previously been created, and has some coded data already... */ + /* Add "pkt" to the frame represented by "node". The "node" has */ + /* previously been created, and has some coded data already... */ - /* New arrivals are added at the head of the list, which is stored */ - /* in descending order of packets as they arrive (NOT necessarily */ - /* descending sequence number order, as the network might reorder) */ + /* New arrivals are added at the head of the list, which is stored */ + /* in descending order of packets as they arrive (NOT necessarily */ + /* descending sequence number order, as the network might reorder) */ - struct coded_data *tmp; + struct coded_data *tmp, *curr, *prv; - assert(node->rtp_timestamp == pkt->ts); - assert(node->cdata != NULL); + assert(node->rtp_timestamp == pkt->ts); + assert(node->cdata != NULL); - tmp = malloc(sizeof(struct coded_data)); - if (tmp != NULL) { - tmp->seqno = pkt->seq; - tmp->data = pkt; - tmp->prv = NULL; - tmp->nxt = node->cdata; - node->cdata->prv = tmp; - node->cdata = tmp; - node->mbit |= pkt->m; + tmp = malloc(sizeof(struct coded_data)); + if (tmp == NULL) { + /* this is bad, out of memory, drop the packet... */ + free(pkt); + return; + } + + tmp->seqno = pkt->seq; + tmp->data = pkt; + node->mbit |= pkt->m; + if((int16_t)(tmp->seqno - node->cdata->seqno) > 0){ + tmp->prv = NULL; + tmp->nxt = node->cdata; + node->cdata->prv = tmp; + node->cdata = tmp; + } else { + curr = node->cdata; + if (curr == NULL){ + /* this is bad, out of memory, drop the packet... */ + free(pkt); + free_cdata(tmp); } else { - /* this is bad, out of memory, drop the packet... */ + while (curr != NULL && ((int16_t)(tmp->seqno - curr->seqno) < 0)){ + prv = curr; + curr = curr->nxt; + } + if (curr == NULL) { + tmp->nxt = NULL; + tmp->prv = prv; + prv->nxt = tmp; + }else if ((int16_t)(tmp->seqno - curr->seqno) > 0){ + tmp->nxt = curr; + tmp->prv = curr->prv; + tmp->prv->nxt = tmp; + curr->prv = tmp; + } else { + /* this is bad, something went terribly wrong... */ free(pkt); + free_cdata(tmp); + } } + } } static struct pbuf_node *create_new_pnode(rtp_packet * pkt, double playout_delay) @@ -239,6 +269,8 @@ static struct pbuf_node *create_new_pnode(rtp_packet * pkt, double playout_delay void pbuf_insert(struct pbuf *playout_buf, rtp_packet * pkt) { struct pbuf_node *tmp; + struct pbuf_node *curr; + pbuf_validate(playout_buf); // collect statistics @@ -283,33 +315,43 @@ void pbuf_insert(struct pbuf *playout_buf, rtp_packet * pkt) return; } - if (playout_buf->last->rtp_timestamp == pkt->ts) { - /* Packet belongs to last frame in playout_buf this is the */ - /* most likely scenario - although... */ - add_coded_unit(playout_buf->last, pkt); + if (playout_buf->last->rtp_timestamp < pkt->ts) { + /* Packet belongs to a new frame... */ + tmp = create_new_pnode(pkt, playout_buf->playout_delay); + playout_buf->last->nxt = tmp; + tmp->prv = playout_buf->last; + playout_buf->last = tmp; } else { - if (playout_buf->last->rtp_timestamp < pkt->ts) { - /* Packet belongs to a new frame... */ - tmp = create_new_pnode(pkt, playout_buf->playout_delay); - playout_buf->last->nxt = tmp; - playout_buf->last->completed = true; - tmp->prv = playout_buf->last; - playout_buf->last = tmp; - } else { - /* Packet belongs to a previous frame... */ - if (playout_buf->frst->rtp_timestamp > pkt->ts) { - debug_msg("A very old packet - discarded\n"); - } else { - debug_msg - ("A packet for a previous frame, but might still be useful\n"); - /* Should probably insert this into the playout buffer here... */ - } - if (pkt->m) { - debug_msg - ("Oops... dropped packet with M bit set\n"); - } - free(pkt); + /* Packet belongs to a previous frame... */ + curr = playout_buf->last; + while(curr != playout_buf->frst && curr->rtp_timestamp > pkt->ts){ + curr = curr->prv; + } + + if (curr->rtp_timestamp == pkt->ts) { + /* Packet belongs to a previous existing frame... */ + add_coded_unit(curr, pkt); + } else if (curr->rtp_timestamp < pkt->ts){ + /* Packet belongs to a new previous frame */ + tmp = create_new_pnode(pkt, playout_buf->playout_delay); + tmp->nxt = curr->nxt; + tmp->prv = curr; + curr->nxt->prv = tmp; + curr->nxt = tmp; + } else if (curr == playout_buf->frst) { + tmp = create_new_pnode(pkt, playout_buf->playout_delay); + tmp->nxt = playout_buf->frst; + curr->prv = tmp; + playout_buf->frst = tmp; + + } else { + + if (pkt->m) { + debug_msg + ("Oops... dropped packet with M bit set\n"); } + free(pkt); + } } pbuf_validate(playout_buf); } diff --git a/src/rtp/rtp.h b/src/rtp/rtp.h index cb1fec293..8043056c5 100644 --- a/src/rtp/rtp.h +++ b/src/rtp/rtp.h @@ -256,7 +256,7 @@ int rtp_send_data_hdr(struct rtp *session, uint32_t rtp_ts, char pt, int m, int cc, uint32_t csrc[], char *phdr, int phdr_len, - char *data, int data_len, + char *data, int data_len, char *extn, uint16_t extn_len, uint16_t extn_type); void rtp_send_ctrl(struct rtp *session, uint32_t rtp_ts, rtcp_app_callback appcallback, struct timeval curr_time); diff --git a/src/rtp/rtpdec_h264.c b/src/rtp/rtpdec_h264.c index 0b5731b55..708b5f417 100644 --- a/src/rtp/rtpdec_h264.c +++ b/src/rtp/rtpdec_h264.c @@ -50,12 +50,16 @@ #include "rtp/rtp_callback.h" #include "rtp/pbuf.h" #include "rtp/rtpdec_h264.h" +#include "utils/h264_stream.h" +#include "utils/bs.h" +#include "video_frame.h" static const uint8_t start_sequence[] = { 0, 0, 0, 1 }; -int decode_frame_h264(struct coded_data *cdata, void *rx_data) { +int fill_coded_frame_from_sps(struct video_frame *rx_data, unsigned char *data, int data_len); + +int decode_frame_h264(struct coded_data *cdata, void *decode_data) { rtp_packet *pckt = NULL; - int substream = 0; struct coded_data *orig = cdata; uint8_t nal; @@ -65,19 +69,21 @@ int decode_frame_h264(struct coded_data *cdata, void *rx_data) { int pass; int total_length = 0; - char *dst = NULL; + unsigned char *dst = NULL; int src_len; - struct std_frame_received *buffers = (struct std_frame_received *) rx_data; + struct video_frame *frame = (struct video_frame *)decode_data; + frame->h264_frame_type = BFRAME; for (pass = 0; pass < 2; pass++) { if (pass > 0) { cdata = orig; - buffers->buffer_len = total_length; - dst = buffers->frame_buffer + total_length; - buffers->bframe = TRUE; - buffers->iframe = FALSE; + if(frame->h264_frame_type == INTRA){ + total_length+=frame->h264_offset_len; + } + frame->h264_buffer_len = total_length; + dst = frame->h264_buffer + total_length; } while (cdata != NULL) { @@ -92,132 +98,133 @@ int decode_frame_h264(struct coded_data *cdata, void *rx_data) { type = nal & 0x1f; nri = nal & 0x60; + if (type == 7){ + fill_coded_frame_from_sps(frame, (unsigned char*) pckt->data, pckt->data_len); + } + if (type >= 1 && type <= 23) { - if (buffers->bframe && !(type == 1 && nri == 0)){ - buffers->bframe = FALSE; - } - if (!buffers->iframe && type == 5 ){ - buffers->iframe =TRUE; + if(frame->h264_frame_type != INTRA && (type == 5 || type == 6)) { + frame->h264_frame_type = INTRA; + } else if (frame->h264_frame_type == BFRAME && nri != 0){ + frame->h264_frame_type = OTHER; } + type = 1; } const uint8_t *src = NULL; switch (type) { - case 0: - case 1: - if (pass == 0) { - debug_msg("NAL type 1\n"); - total_length += sizeof(start_sequence) + pckt->data_len; - } else { - dst -= pckt->data_len + sizeof(start_sequence); - memcpy(dst, start_sequence, sizeof(start_sequence)); - memcpy(dst + sizeof(start_sequence), pckt->data, pckt->data_len); - unsigned char *dst2 = (unsigned char *)dst; - } - break; - case 24: - src = (const uint8_t *) pckt->data; - src_len = pckt->data_len; - - src++; - src_len--; - - while (src_len > 2) { - //TODO: Not properly tested - //TODO: bframes and iframes detection - uint16_t nal_size; - memcpy(&nal_size, src, sizeof(uint16_t)); - - src += 2; - src_len -= 2; - - if (nal_size <= src_len) { - if (pass == 0) { - total_length += sizeof(start_sequence) + nal_size; - } else { - dst -= nal_size + sizeof(start_sequence); - memcpy(dst, start_sequence, sizeof(start_sequence)); - memcpy(dst + sizeof(start_sequence), src, nal_size); - } + case 0: + case 1: + if (pass == 0) { + debug_msg("NAL type 1\n"); + total_length += sizeof(start_sequence) + pckt->data_len; } else { - error_msg("NAL size exceeds length: %u %d\n", nal_size, src_len); - return FALSE; + dst -= pckt->data_len + sizeof(start_sequence); + memcpy(dst, start_sequence, sizeof(start_sequence)); + memcpy(dst + sizeof(start_sequence), pckt->data, pckt->data_len); } - src += nal_size; - src_len -= nal_size; + break; + case 24: + src = (const uint8_t *) pckt->data; + src_len = pckt->data_len; - if (src_len < 0) { - error_msg("Consumed more bytes than we got! (%d)\n", src_len); - return FALSE; + src++; + src_len--; + + while (src_len > 2) { + //TODO: Not properly tested + //TODO: bframes and iframes detection + uint16_t nal_size; + memcpy(&nal_size, src, sizeof(uint16_t)); + + src += 2; + src_len -= 2; + + if (nal_size <= src_len) { + if (pass == 0) { + total_length += sizeof(start_sequence) + nal_size; + } else { + dst -= nal_size + sizeof(start_sequence); + memcpy(dst, start_sequence, sizeof(start_sequence)); + memcpy(dst + sizeof(start_sequence), src, nal_size); + } + } else { + error_msg("NAL size exceeds length: %u %d\n", nal_size, src_len); + return FALSE; + } + src += nal_size; + src_len -= nal_size; + + if (src_len < 0) { + error_msg("Consumed more bytes than we got! (%d)\n", src_len); + return FALSE; + } } - } - break; + break; case 25: case 26: case 27: case 29: - error_msg("Unhandled NAL type\n"); - return FALSE; + error_msg("Unhandled NAL type\n"); + return FALSE; case 28: - src = (const uint8_t *) pckt->data; - src_len = pckt->data_len; + src = (const uint8_t *) pckt->data; + src_len = pckt->data_len; - src++; - src_len--; - - if (src_len > 1) { - uint8_t fu_header = *src; - uint8_t start_bit = fu_header >> 7; - //uint8_t end_bit = (fu_header & 0x40) >> 6; - uint8_t nal_type = fu_header & 0x1f; - uint8_t reconstructed_nal; - - if (buffers->bframe && !(nal_type == 1 && nri == 0)){ - buffers->bframe = FALSE; - } - - if (!buffers->iframe && nal_type == 5){ - buffers->iframe = TRUE; - } - - // Reconstruct this packet's true nal; only the data follows. - /* The original nal forbidden bit and NRI are stored in this - * packet's nal. */ - reconstructed_nal = nal & 0xe0; - reconstructed_nal |= nal_type; - - // skip the fu_header src++; src_len--; - if (pass == 0) { - if (start_bit) { - total_length += sizeof(start_sequence) + sizeof(reconstructed_nal) + src_len; + if (src_len > 1) { + uint8_t fu_header = *src; + uint8_t start_bit = fu_header >> 7; + //uint8_t end_bit = (fu_header & 0x40) >> 6; + uint8_t nal_type = fu_header & 0x1f; + uint8_t reconstructed_nal; + + if(frame->h264_frame_type != INTRA && (nal_type == 5 || nal_type == 6)){ + frame->h264_frame_type = INTRA; + } else if (frame->h264_frame_type == BFRAME && nri != 0){ + frame->h264_frame_type = OTHER; + } + + // Reconstruct this packet's true nal; only the data follows. + /* The original nal forbidden bit and NRI are stored in this + * packet's nal. */ + reconstructed_nal = nal & 0xe0; + reconstructed_nal |= nal_type; + + // skip the fu_header + src++; + src_len--; + + if (pass == 0) { + if (start_bit) { + total_length += sizeof(start_sequence) + sizeof(reconstructed_nal) + src_len; + } else { + total_length += src_len; + } } else { - total_length += src_len; + if (start_bit) { + dst -= sizeof(start_sequence) + sizeof(reconstructed_nal) + src_len; + memcpy(dst, start_sequence, sizeof(start_sequence)); + memcpy(dst + sizeof(start_sequence), &reconstructed_nal, sizeof(reconstructed_nal)); + memcpy(dst + sizeof(start_sequence) + sizeof(reconstructed_nal), src, src_len); + } else { + dst -= src_len; + memcpy(dst, src, src_len); + } } } else { - if (start_bit) { - dst -= sizeof(start_sequence) + sizeof(reconstructed_nal) + src_len; - memcpy(dst, start_sequence, sizeof(start_sequence)); - memcpy(dst + sizeof(start_sequence), &reconstructed_nal, sizeof(reconstructed_nal)); - memcpy(dst + sizeof(start_sequence) + sizeof(reconstructed_nal), src, src_len); - } else { - dst -= src_len; - memcpy(dst, src, src_len); - } + error_msg("Too short data for FU-A H264 RTP packet\n"); + return FALSE; } - } else { - error_msg("Too short data for FU-A H264 RTP packet\n"); - return FALSE; - } - break; + break; default: - error_msg("Unknown NAL type\n"); - return FALSE; + error_msg("Unknown NAL type\n"); + return FALSE; } cdata = cdata->nxt; } @@ -225,3 +232,86 @@ int decode_frame_h264(struct coded_data *cdata, void *rx_data) { return TRUE; } + +int fill_coded_frame_from_sps(struct video_frame *rx_data, unsigned char *data, int data_len){ + uint32_t width, height; + sps_t* sps = (sps_t*)malloc(sizeof(sps_t)); + uint8_t* rbsp_buf = (uint8_t*)malloc(data_len); + if (nal_to_rbsp(data, &data_len, rbsp_buf, &data_len) < 0){ + free(rbsp_buf); + free(sps); + return -1; + } + bs_t* b = bs_new(rbsp_buf, data_len); + if(read_seq_parameter_set_rbsp(sps,b) < 0){ + bs_free(b); + free(rbsp_buf); + free(sps); + return -1; + } + width = (sps->pic_width_in_mbs_minus1 + 1) * 16; + height = (2 - sps->frame_mbs_only_flag) * (sps->pic_height_in_map_units_minus1 + 1) * 16; + //NOTE: frame_mbs_only_flag = 1 --> only progressive frames + // frame_mbs_only_flag = 0 --> some type of interlacing (there are 3 types contemplated in the standard) + if (sps->frame_cropping_flag){ + width -= (sps->frame_crop_left_offset*2 + sps->frame_crop_right_offset*2); + height -= (sps->frame_crop_top_offset*2 + sps->frame_crop_bottom_offset*2); + } + + if((width != rx_data->h264_width) || (height != rx_data->h264_height)) { + rx_data->h264_width = width; + rx_data->h264_height = height; + vf_get_tile(rx_data, 0)->width = width; + vf_get_tile(rx_data, 0)->height = height; +// free(rx_data->tiles[0].data); +// rx_data->tiles[0].data = calloc(1, rx_data->h264_width * rx_data->h264_height); + } + + bs_free(b); + free(rbsp_buf); + free(sps); + + return 0; +} + +int width_height_from_SDP(int *widthOut, int *heightOut , unsigned char *data, int data_len){ + uint32_t width, height; + sps_t* sps = (sps_t*)malloc(sizeof(sps_t)); + uint8_t* rbsp_buf = (uint8_t*)malloc(data_len); + if (nal_to_rbsp(data, &data_len, rbsp_buf, &data_len) < 0){ + free(rbsp_buf); + free(sps); + return -1; + } + bs_t* b = bs_new(rbsp_buf, data_len); + if(read_seq_parameter_set_rbsp(sps,b) < 0){ + bs_free(b); + free(rbsp_buf); + free(sps); + return -1; + } + width = (sps->pic_width_in_mbs_minus1 + 1) * 16; + height = (2 - sps->frame_mbs_only_flag) * (sps->pic_height_in_map_units_minus1 + 1) * 16; + //NOTE: frame_mbs_only_flag = 1 --> only progressive frames + // frame_mbs_only_flag = 0 --> some type of interlacing (there are 3 types contemplated in the standard) + if (sps->frame_cropping_flag){ + width -= (sps->frame_crop_left_offset*2 + sps->frame_crop_right_offset*2); + height -= (sps->frame_crop_top_offset*2 + sps->frame_crop_bottom_offset*2); + } + + debug_msg("\n\n[width_height_from_SDP] width: %d height: %d\n\n",width,height); + + + if(width > 0){ + *widthOut = width; + } + if(height > 0){ + *heightOut = height; + } + + bs_free(b); + free(rbsp_buf); + free(sps); + + return 0; +} diff --git a/src/rtp/rtpdec_h264.h b/src/rtp/rtpdec_h264.h index 61b7c6352..9e9cf02bb 100644 --- a/src/rtp/rtpdec_h264.h +++ b/src/rtp/rtpdec_h264.h @@ -44,15 +44,7 @@ #ifndef _RTP_DEC_H264_H #define _RTP_DEC_H264_H -struct std_frame_received { - uint32_t buffer_len; //[MAX_SUBSTREAMS]; - //uint32_t buffer_num;//[MAX_SUBSTREAMS]; - char *frame_buffer; //[MAX_SUBSTREAMS]; - uint8_t bframe; - uint8_t iframe; -}; - -int -decode_frame_h264(struct coded_data *cdata, void *rx_data); +int decode_frame_h264(struct coded_data *cdata, void *decode_data); +int width_height_from_SDP(int *widthOut, int *heightOut , unsigned char *data, int data_len); #endif diff --git a/src/rtsp/BasicRTSPOnlyServer.cpp b/src/rtsp/BasicRTSPOnlyServer.cpp index 7f99c0dfb..cd0f11f2b 100644 --- a/src/rtsp/BasicRTSPOnlyServer.cpp +++ b/src/rtsp/BasicRTSPOnlyServer.cpp @@ -48,7 +48,7 @@ BasicRTSPOnlyServer *BasicRTSPOnlyServer::srvInstance = NULL; -BasicRTSPOnlyServer::BasicRTSPOnlyServer(int port, struct module *mod, uint8_t avType){ +BasicRTSPOnlyServer::BasicRTSPOnlyServer(int port, struct module *mod, rtps_types_t avType){ if(mod == NULL){ exit(1); } @@ -61,7 +61,7 @@ BasicRTSPOnlyServer::BasicRTSPOnlyServer(int port, struct module *mod, uint8_t a } BasicRTSPOnlyServer* -BasicRTSPOnlyServer::initInstance(int port, struct module *mod, uint8_t avType){ +BasicRTSPOnlyServer::initInstance(int port, struct module *mod, rtps_types_t avType){ if (srvInstance != NULL){ return srvInstance; } @@ -78,10 +78,13 @@ BasicRTSPOnlyServer::getInstance(){ int BasicRTSPOnlyServer::init_server() { - if (env != NULL || rtspServer != NULL || mod == NULL || (avType > 2 && avType < 0)){ + if (env != NULL || rtspServer != NULL || mod == NULL || (avType >= NUM_RTSP_FORMATS && avType < 0)){ exit(1); } + //setting livenessTimeoutTask + unsigned reclamationTestSeconds = 35; + TaskScheduler* scheduler = BasicTaskScheduler::createNew(); env = BasicUsageEnvironment::createNew(*scheduler); @@ -98,7 +101,7 @@ int BasicRTSPOnlyServer::init_server() { fPort = 8554; } - rtspServer = RTSPServer::createNew(*env, fPort, authDB); + rtspServer = RTSPServer::createNew(*env, fPort, authDB, reclamationTestSeconds); if (rtspServer == NULL) { *env << "Failed to create RTSP server: " << env->getResultMsg() << "\n"; exit(1); @@ -108,11 +111,16 @@ int BasicRTSPOnlyServer::init_server() { "UltraGrid RTSP server enabling standard transport", "UltraGrid RTSP server"); - if(avType == 0){ + if(avType == avStdDyn){ + sms->addSubsession(BasicRTSPOnlySubsession + ::createNew(*env, True, mod, audioPCMUdyn)); + sms->addSubsession(BasicRTSPOnlySubsession + ::createNew(*env, True, mod, videoH264)); + }else if(avType == avStd){ sms->addSubsession(BasicRTSPOnlySubsession - ::createNew(*env, True, mod, 2)); + ::createNew(*env, True, mod, audioPCMUstd)); sms->addSubsession(BasicRTSPOnlySubsession - ::createNew(*env, True, mod, 1)); + ::createNew(*env, True, mod, videoH264)); }else sms->addSubsession(BasicRTSPOnlySubsession ::createNew(*env, True, mod, avType)); diff --git a/src/rtsp/BasicRTSPOnlyServer.hh b/src/rtsp/BasicRTSPOnlyServer.hh index 8705d13ef..983260a6d 100644 --- a/src/rtsp/BasicRTSPOnlyServer.hh +++ b/src/rtsp/BasicRTSPOnlyServer.hh @@ -47,16 +47,17 @@ #include #include +#include "rtsp/rtsp_utils.h" #include "module.h" class BasicRTSPOnlyServer { private: - BasicRTSPOnlyServer(int port, struct module *mod, uint8_t avType); + BasicRTSPOnlyServer(int port, struct module *mod, rtps_types_t avType); public: - static BasicRTSPOnlyServer* initInstance(int port, struct module *mod, uint8_t avType); + static BasicRTSPOnlyServer* initInstance(int port, struct module *mod, rtps_types_t avType); static BasicRTSPOnlyServer* getInstance(); int init_server(); @@ -70,7 +71,7 @@ private: static BasicRTSPOnlyServer* srvInstance; int fPort; struct module *mod; - uint8_t avType; + rtps_types_t avType; RTSPServer* rtspServer; UsageEnvironment* env; }; diff --git a/src/rtsp/BasicRTSPOnlySubsession.cpp b/src/rtsp/BasicRTSPOnlySubsession.cpp index 31bf37940..8c8f3010b 100644 --- a/src/rtsp/BasicRTSPOnlySubsession.cpp +++ b/src/rtsp/BasicRTSPOnlySubsession.cpp @@ -52,14 +52,14 @@ BasicRTSPOnlySubsession* BasicRTSPOnlySubsession::createNew(UsageEnvironment& env, Boolean reuseFirstSource, - struct module *mod, uint8_t avType){ + struct module *mod, rtps_types_t avType){ return new BasicRTSPOnlySubsession(env, reuseFirstSource, mod, avType); } BasicRTSPOnlySubsession ::BasicRTSPOnlySubsession(UsageEnvironment& env, Boolean reuseFirstSource, - struct module *mod, uint8_t avType) + struct module *mod, rtps_types_t avType) : ServerMediaSubsession(env), fSDPLines(NULL), fReuseFirstSource(reuseFirstSource), fLastStreamToken(NULL) { @@ -89,7 +89,7 @@ void BasicRTSPOnlySubsession ::setSDPLines() { //TODO: should be more dynamic //VStream - if(avType == 1){ + if(avType == videoH264 || avType == avStdDyn || avType == avStd){ unsigned estBitrate = 5000; char const* mediaType = "video"; uint8_t rtpPayloadType = 96; @@ -123,7 +123,7 @@ void BasicRTSPOnlySubsession fSDPLines = sdpLines; } //AStream - if(avType == 2){ + if(avType == audioPCMUdyn || avType == avStdDyn){ unsigned estBitrate = 384; char const* mediaType = "audio"; uint8_t rtpPayloadType = 97; @@ -172,7 +172,7 @@ void BasicRTSPOnlySubsession::getStreamParameters(unsigned clientSessionId, Port& serverRTCPPort, void*& streamToken) { - if(Vdestination == NULL && avType == 1){ + if(Vdestination == NULL && (avType == videoH264 || avType == avStdDyn || avType == avStd)){ if (fSDPLines == NULL){ setSDPLines(); } @@ -183,7 +183,7 @@ void BasicRTSPOnlySubsession::getStreamParameters(unsigned clientSessionId, destinationAddr.s_addr = destinationAddress; Vdestination = new Destinations(destinationAddr, clientRTPPort,clientRTCPPort); } - if(Adestination == NULL && avType == 2){ + if(Adestination == NULL && (avType == audioPCMUdyn || avType == avStdDyn)){ if (fSDPLines == NULL){ setSDPLines(); } @@ -205,15 +205,12 @@ void BasicRTSPOnlySubsession::startStream(unsigned clientSessionId, unsigned& rtpTimestamp, ServerRequestAlternativeByteHandler* serverRequestAlternativeByteHandler, void* serverRequestAlternativeByteHandlerClientData) { + struct response *resp = NULL; - if ((Vdestination == NULL && Adestination == NULL)){ - return; - } else{ - struct response *resp = NULL; - char pathV[1024]; - char pathA[1024]; + if (Vdestination != NULL){ + if(avType == videoH264 || avType == avStdDyn || avType == avStd){ + char pathV[1024]; - if(avType == 1 && Vdestination != NULL){ memset(pathV, 0, sizeof(pathV)); enum module_class path_sender[] = { MODULE_CLASS_SENDER, MODULE_CLASS_NONE }; append_message_path(pathV, sizeof(pathV), path_sender); @@ -237,9 +234,12 @@ void BasicRTSPOnlySubsession::startStream(unsigned clientSessionId, resp = send_message(fmod, pathV, (struct message *) msgV2); resp = NULL; } - if(avType == 2 && Adestination != NULL){ - struct msg_sender *msg = (struct msg_sender *) - new_message(sizeof(struct msg_sender)); + } + + if(Adestination != NULL){ + if(avType == audioPCMUdyn || avType == avStdDyn){ + char pathA[1024]; + memset(pathA, 0, sizeof(pathA)); enum module_class path_sender[] = { MODULE_CLASS_AUDIO, MODULE_CLASS_SENDER, MODULE_CLASS_NONE }; append_message_path(pathA, sizeof(pathA), path_sender); @@ -267,15 +267,10 @@ void BasicRTSPOnlySubsession::startStream(unsigned clientSessionId, } void BasicRTSPOnlySubsession::deleteStream(unsigned clientSessionId, void*& streamToken){ - if ((Vdestination == NULL && Adestination == NULL)){ - return; - } else { - char pathV[1024]; - char pathA[1024]; - Vdestination = NULL; - Adestination = NULL; - - if(avType == 1 || Vdestination != NULL){ + if (Vdestination != NULL){ + if(avType == videoH264 || avType == avStdDyn || avType == avStd){ + char pathV[1024]; + Vdestination = NULL; memset(pathV, 0, sizeof(pathV)); enum module_class path_sender[] = { MODULE_CLASS_SENDER, MODULE_CLASS_NONE }; append_message_path(pathV, sizeof(pathV), path_sender); @@ -295,7 +290,12 @@ void BasicRTSPOnlySubsession::deleteStream(unsigned clientSessionId, void*& stre msgV2->type = SENDER_MSG_CHANGE_RECEIVER; send_message(fmod, pathV, (struct message *) msgV2); } - if(avType == 2 || Adestination != NULL){ + } + + if(Adestination != NULL){ + if(avType == audioPCMUdyn || avType == avStdDyn){ + char pathA[1024]; + Adestination = NULL; memset(pathA, 0, sizeof(pathA)); enum module_class path_sender[] = { MODULE_CLASS_AUDIO, MODULE_CLASS_SENDER, MODULE_CLASS_NONE }; append_message_path(pathA, sizeof(pathA), path_sender); diff --git a/src/rtsp/BasicRTSPOnlySubsession.hh b/src/rtsp/BasicRTSPOnlySubsession.hh index 32d23d168..5fbfd27e9 100644 --- a/src/rtsp/BasicRTSPOnlySubsession.hh +++ b/src/rtsp/BasicRTSPOnlySubsession.hh @@ -52,6 +52,7 @@ extern "C" { #endif +#include "rtsp/rtsp_utils.h" #include "module.h" #include "control_socket.h" @@ -91,12 +92,12 @@ public: createNew(UsageEnvironment& env, Boolean reuseFirstSource, struct module *mod, - uint8_t avType); + rtps_types_t avType); protected: BasicRTSPOnlySubsession(UsageEnvironment& env, Boolean reuseFirstSource, - struct module *mod, uint8_t avType); + struct module *mod, rtps_types_t avType); virtual ~BasicRTSPOnlySubsession(); @@ -139,7 +140,7 @@ private: void* fLastStreamToken; char fCNAME[100]; struct module *fmod; - uint8_t avType; + rtps_types_t avType; }; diff --git a/src/rtsp/c_basicRTSPOnlyServer.cpp b/src/rtsp/c_basicRTSPOnlyServer.cpp index 6227e3a66..02a2bcbca 100644 --- a/src/rtsp/c_basicRTSPOnlyServer.cpp +++ b/src/rtsp/c_basicRTSPOnlyServer.cpp @@ -57,7 +57,7 @@ int c_start_server(rtsp_serv_t* server){ return ret; } -rtsp_serv_t *init_rtsp_server(unsigned int port, struct module *mod, uint8_t avType){ +rtsp_serv_t *init_rtsp_server(unsigned int port, struct module *mod, rtps_types_t avType){ rtsp_serv_t *server = (rtsp_serv_t*) malloc(sizeof(rtsp_serv_t)); server->port = port; server->mod = mod; diff --git a/src/rtsp/c_basicRTSPOnlyServer.h b/src/rtsp/c_basicRTSPOnlyServer.h index 8c1bc86ed..92a8ee2d8 100644 --- a/src/rtsp/c_basicRTSPOnlyServer.h +++ b/src/rtsp/c_basicRTSPOnlyServer.h @@ -59,6 +59,7 @@ extern "C" { #include "control_socket.h" #include "module.h" #include "debug.h" +#include "rtsp/rtsp_utils.h" #ifdef __cplusplus } @@ -77,14 +78,14 @@ EXTERNC typedef struct rtsp_serv { pthread_t server_th; uint8_t watch; uint8_t run; - uint8_t avType; + rtps_types_t avType; } rtsp_serv_t; EXTERNC int c_start_server(rtsp_serv_t* server); EXTERNC void c_stop_server(rtsp_serv_t* server); -EXTERNC rtsp_serv_t* init_rtsp_server(unsigned int port, struct module *mod, uint8_t avType); +EXTERNC rtsp_serv_t* init_rtsp_server(unsigned int port, struct module *mod, rtps_types_t avType); #undef EXTERNC diff --git a/src/rtsp/rtsp_utils.h b/src/rtsp/rtsp_utils.h new file mode 100644 index 000000000..8141e9160 --- /dev/null +++ b/src/rtsp/rtsp_utils.h @@ -0,0 +1,17 @@ +#ifndef _RTSP_TYPES_HH +#define _RTSP_TYPES_HH + +typedef enum { + none, + avStd, + avStdDyn, + avUG, + videoH264, + videoUG, + audioPCMUstd, + audioPCMUdyn, + NUM_RTSP_FORMATS +}rtps_types_t; + + +#endif diff --git a/src/transmit.c b/src/transmit.c index fd285e3af..f66c69717 100644 --- a/src/transmit.c +++ b/src/transmit.c @@ -154,7 +154,7 @@ struct tx { // Mulaw audio memory reservation static void init_tx_mulaw_buffer() { if (!buffer_mulaw_init) { - data_buffer_mulaw = malloc(BUFFER_MTU_SIZE); + data_buffer_mulaw = malloc(BUFFER_MTU_SIZE*20); buffer_mulaw_init = 1; } } @@ -379,7 +379,6 @@ void format_video_header(struct video_frame *frame, int tile_idx, int buffer_idx void tx_send_tile(struct tx *tx, struct video_frame *frame, int pos, struct rtp *rtp_session) { - struct tile *tile; int last = FALSE; uint32_t ts = 0; int fragment_offset = 0; @@ -389,7 +388,6 @@ tx_send_tile(struct tx *tx, struct video_frame *frame, int pos, struct rtp *rtp_ platform_spin_lock(&tx->spin); - tile = vf_get_tile(frame, pos); ts = get_local_mediatime(); if(frame->fragment && tx->last_frame_fragment_id == frame->frame_fragment_id) { @@ -763,6 +761,8 @@ void audio_tx_send(struct tx* tx, struct rtp *rtp_session, audio_frame2 * buffer */ void audio_tx_send_mulaw(struct tx* tx, struct rtp *rtp_session, audio_frame2 * buffer) { + assert(buffer->codec == AC_MULAW); + int pt; uint32_t timestamp; @@ -772,7 +772,6 @@ void audio_tx_send_mulaw(struct tx* tx, struct rtp *rtp_session, audio_frame2 * // 8000 Hz, 1 channel is the ITU-T G.711 standard // More channels or Hz goes to DynRTP-Type97 -//TODO CHECK ACTUAL CHCOUNT IN ORDER TO PROPERLY CREATE PAYLOAD TYPE if (buffer->ch_count == 1 && buffer->sample_rate == 8000) { pt = PT_ITU_T_G711_PCMU; } else { @@ -782,50 +781,45 @@ void audio_tx_send_mulaw(struct tx* tx, struct rtp *rtp_session, audio_frame2 * // The sizes for the different audio_frame2 channels must be the same. for (int i = 1 ; i < buffer->ch_count ; i++) assert(buffer->data_len[0] == buffer->data_len[i]); - int data_len = buffer->data_len[0] * buffer->ch_count; /* Number of samples to send (bps=1)*/ + int data_len = buffer->data_len[0] * buffer->ch_count; /* Number of samples to send */ int data_remainig = data_len; - int payload_size = tx->mtu - 40; /* Max size of an RTP payload field */ - int packets = data_len / payload_size; - if (data_len % payload_size != 0) packets++; /* Number of RTP packets needed */ + int payload_size = tx->mtu - 40; /* Max size of an RTP payload field */ init_tx_mulaw_buffer(); char *curr_sample = data_buffer_mulaw; - // For each interval that fits in an RTP payload field. - for (int p = 0 ; p < packets ; p++) { + int ch, pos = 0, count = 0, pointerToSend = 0; - int samples_per_packet; - int data_to_send; - if (data_remainig >= payload_size) { - samples_per_packet = payload_size / buffer->ch_count; - data_to_send = payload_size; - } - else { - samples_per_packet = data_remainig / buffer->ch_count; - data_to_send = data_remainig; - } + do{ + for(ch = 0; ch < buffer->ch_count; ch++){ + memcpy(curr_sample, buffer->data[ch] + pos, buffer->bps * sizeof(char)); + curr_sample += buffer->bps * sizeof(char); + count+=buffer->bps * sizeof(char); + data_remainig--; + } + pos += buffer->bps * sizeof(char); - // Interleave the samples - for (int ch_sample = 0 ; ch_sample < samples_per_packet ; ch_sample++){ - for (int ch = 0 ; ch < buffer->ch_count ; ch++) { - //TODO to be checked prepiously -> if(buffer->data[ch]!=NULL){ - memcpy(curr_sample, (char *)(buffer->data[ch] + ch_sample), sizeof(uint8_t)); - curr_sample += sizeof(uint8_t); - data_remainig--; - // } - } - } + if((pos * buffer->ch_count) % payload_size == 0){ + // Update first sample timestamp + timestamp = get_std_audio_local_mediatime((buffer->data_len[0] - (data_remainig/(buffer->bps * buffer->ch_count)))); + // Send the packet + rtp_send_data(rtp_session, timestamp, pt, 0, 0, /* contributing sources */ + 0, /* contributing sources length */ + data_buffer_mulaw + pointerToSend, payload_size, + 0, 0, 0); + pointerToSend += payload_size; + } + }while(count < data_len); - // Update first sample timestamp - timestamp = get_std_audio_local_mediatime((buffer->data_len[0] - (data_remainig/buffer->ch_count))); - - // Send the packet - rtp_send_data(rtp_session, timestamp, pt, 0, 0, /* contributing sources */ - 0, /* contributing sources length */ - data_buffer_mulaw, data_to_send, - 0, 0, 0); + if((pos * buffer->ch_count) % payload_size != 0){ + // Update first sample timestamp + timestamp = get_std_audio_local_mediatime((buffer->data_len[0] - (data_remainig/(buffer->bps * buffer->ch_count)))); + // Send the packet + rtp_send_data(rtp_session, timestamp, pt, 0, 0, /* contributing sources */ + 0, /* contributing sources length */ + data_buffer_mulaw + pointerToSend , (pos * buffer->ch_count) % payload_size, + 0, 0, 0); } - tx->buffer ++; platform_spin_unlock(&tx->spin); @@ -840,10 +834,10 @@ int rtpenc_h264_parse_nal_units(uint8_t *buf_in, int size, static uint8_t *rtpenc_h264_find_startcode_internal(uint8_t *start, uint8_t *end) { - uint8_t *p = start; - uint8_t *pend = end; // - 3; // XXX: w/o -3, p[1] and p[2] may fail. + //uint8_t *p = start; + //uint8_t *pend = end; // - 3; // XXX: w/o -3, p[1] and p[2] may fail. - for (p = start; p < pend; p++) { + for (uint8_t *p = start; p < end; p++) { if (p[0] == 0 && p[1] == 0 && p[2] == 1) { return p; } @@ -888,13 +882,14 @@ int rtpenc_h264_parse_nal_units(uint8_t *buf_in, int size, } int nal_size = nal_end - nal_start; - size += nal_size; + if(nal_size > 4){ + size += nal_size; + nals[(*nnals)].data = nal_start; + nals[(*nnals)].size = nal_size; + (*nnals)++; - nals[(*nnals)].data = nal_start; - nals[(*nnals)].size = nal_size; - (*nnals)++; - - nal_start = nal_end; + nal_start = nal_end; + }else nal_start += 3; } return size; } @@ -937,6 +932,7 @@ static void tx_send_base_h264(struct tx *tx, struct tile *tile, struct rtp *rtp_ int fragmentation = 0; int nal_max_size = tx->mtu - 40; + if (nal.size > nal_max_size) { debug_msg("RTP packet size exceeds the MTU size\n"); fragmentation = 1; @@ -1024,7 +1020,6 @@ static void tx_send_base_h264(struct tx *tx, struct tile *tile, struct rtp *rtp_ } } else { - uint8_t frag_header[2]; int frag_header_size = 2; diff --git a/src/types.h b/src/types.h index 0e0557226..19085ff01 100644 --- a/src/types.h +++ b/src/types.h @@ -111,6 +111,12 @@ struct video_desc { unsigned int tile_count; }; +typedef enum h264_frame_type { + INTRA, + BFRAME, + OTHER +} h264_frame_type_t; + enum fec_type { FEC_NONE = 0, FEC_MULT = 1, @@ -179,11 +185,21 @@ struct video_frame { //standard transport uint8_t isStd; - //h264_params - uint8_t h264_bframe; - uint8_t h264_iframe; - int h264_width; - int h264_height; + //H264 Standard transport + // Config + unsigned int h264_width; + unsigned int h264_height; + codec_t codec; + // Data + unsigned char *h264_buffer; + unsigned int h264_buffer_len; + unsigned int h264_offset_len; + unsigned char *h264_offset_buffer; + // Stats + unsigned int h264_media_time; + unsigned int h264_seqno; + // Control + h264_frame_type_t h264_frame_type; struct fec_desc fec_params; }; diff --git a/src/utils/bs.h b/src/utils/bs.h new file mode 100644 index 000000000..c5087cdea --- /dev/null +++ b/src/utils/bs.h @@ -0,0 +1,388 @@ +/* + * h264bitstream - a library for reading and writing H.264 video + * Copyright (C) 2005-2007 Auroras Entertainment, LLC + * Copyright (C) 2008-2011 Avail-TVN + * + * Written by Alex Izvorski and Alex Giladi + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef _H264_BS_H +#define _H264_BS_H 1 + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct +{ + uint8_t* start; + uint8_t* p; + uint8_t* end; + int bits_left; +} bs_t; + +#define _OPTIMIZE_BS_ 1 + +#if ( _OPTIMIZE_BS_ > 0 ) +#ifndef FAST_U8 +#define FAST_U8 +#endif +#endif + + +static bs_t* bs_new(uint8_t* buf, size_t size); +static void bs_free(bs_t* b); +static bs_t* bs_clone( bs_t* dest, const bs_t* src ); +static bs_t* bs_init(bs_t* b, uint8_t* buf, size_t size); +static uint32_t bs_byte_aligned(bs_t* b); +static int bs_eof(bs_t* b); +static int bs_overrun(bs_t* b); +static int bs_pos(bs_t* b); + +static uint32_t bs_peek_u1(bs_t* b); +static uint32_t bs_read_u1(bs_t* b); +static uint32_t bs_read_u(bs_t* b, int n); +static uint32_t bs_read_f(bs_t* b, int n); +static uint32_t bs_read_u8(bs_t* b); +static uint32_t bs_read_ue(bs_t* b); +static int32_t bs_read_se(bs_t* b); + +static void bs_write_u1(bs_t* b, uint32_t v); +static void bs_write_u(bs_t* b, int n, uint32_t v); +static void bs_write_f(bs_t* b, int n, uint32_t v); +static void bs_write_u8(bs_t* b, uint32_t v); +static void bs_write_ue(bs_t* b, uint32_t v); +static void bs_write_se(bs_t* b, int32_t v); + +static int bs_read_bytes(bs_t* b, uint8_t* buf, int len); +static int bs_write_bytes(bs_t* b, uint8_t* buf, int len); +static int bs_skip_bytes(bs_t* b, int len); +static uint32_t bs_next_bits(bs_t* b, int nbits); +// IMPLEMENTATION + +static inline bs_t* bs_init(bs_t* b, uint8_t* buf, size_t size) +{ + b->start = buf; + b->p = buf; + b->end = buf + size; + b->bits_left = 8; + return b; +} + +static inline bs_t* bs_new(uint8_t* buf, size_t size) +{ + bs_t* b = (bs_t*)malloc(sizeof(bs_t)); + bs_init(b, buf, size); + return b; +} + +static inline void bs_free(bs_t* b) +{ + free(b); +} + +static inline bs_t* bs_clone(bs_t* dest, const bs_t* src) +{ + dest->start = src->p; + dest->p = src->p; + dest->end = src->end; + dest->bits_left = src->bits_left; + return dest; +} + +static inline uint32_t bs_byte_aligned(bs_t* b) +{ + return (b->bits_left == 8); +} + +static inline int bs_eof(bs_t* b) { if (b->p >= b->end) { return 1; } else { return 0; } } + +static inline int bs_overrun(bs_t* b) { if (b->p > b->end) { return 1; } else { return 0; } } + +static inline int bs_pos(bs_t* b) { if (b->p > b->end) { return (b->end - b->start); } else { return (b->p - b->start); } } + +static inline int bs_bytes_left(bs_t* b) { return (b->end - b->p); } + +static inline uint32_t bs_read_u1(bs_t* b) +{ + uint32_t r = 0; + + b->bits_left--; + + if (! bs_eof(b)) + { + r = ((*(b->p)) >> b->bits_left) & 0x01; + } + + if (b->bits_left == 0) { b->p ++; b->bits_left = 8; } + + return r; +} + +static inline void bs_skip_u1(bs_t* b) +{ + b->bits_left--; + if (b->bits_left == 0) { b->p ++; b->bits_left = 8; } +} + +static inline uint32_t bs_peek_u1(bs_t* b) +{ + uint32_t r = 0; + + if (! bs_eof(b)) + { + r = ((*(b->p)) >> ( b->bits_left - 1 )) & 0x01; + } + return r; +} + + +static inline uint32_t bs_read_u(bs_t* b, int n) +{ + uint32_t r = 0; + int i; + for (i = 0; i < n; i++) + { + r |= ( bs_read_u1(b) << ( n - i - 1 ) ); + } + return r; +} + +static inline void bs_skip_u(bs_t* b, int n) +{ + int i; + for ( i = 0; i < n; i++ ) + { + bs_skip_u1( b ); + } +} + +static inline uint32_t bs_read_f(bs_t* b, int n) { return bs_read_u(b, n); } + +static inline uint32_t bs_read_u8(bs_t* b) +{ +#ifdef FAST_U8 + if (b->bits_left == 8 && ! bs_eof(b)) // can do fast read + { + uint32_t r = b->p[0]; + b->p++; + return r; + } +#endif + return bs_read_u(b, 8); +} + +static inline uint32_t bs_read_ue(bs_t* b) +{ + int32_t r = 0; + int i = 0; + + while( (bs_read_u1(b) == 0) && (i < 32) && (!bs_eof(b)) ) + { + i++; + } + r = bs_read_u(b, i); + r += (1 << i) - 1; + return r; +} + +static inline int32_t bs_read_se(bs_t* b) +{ + int32_t r = bs_read_ue(b); + if (r & 0x01) + { + r = (r+1)/2; + } + else + { + r = -(r/2); + } + return r; +} + + +static inline void bs_write_u1(bs_t* b, uint32_t v) +{ + b->bits_left--; + + if (! bs_eof(b)) + { + // FIXME this is slow, but we must clear bit first + // is it better to memset(0) the whole buffer during bs_init() instead? + // if we don't do either, we introduce pretty nasty bugs + (*(b->p)) &= ~(0x01 << b->bits_left); + (*(b->p)) |= ((v & 0x01) << b->bits_left); + } + + if (b->bits_left == 0) { b->p ++; b->bits_left = 8; } +} + +static inline void bs_write_u(bs_t* b, int n, uint32_t v) +{ + int i; + for (i = 0; i < n; i++) + { + bs_write_u1(b, (v >> ( n - i - 1 ))&0x01 ); + } +} + +static inline void bs_write_f(bs_t* b, int n, uint32_t v) { bs_write_u(b, n, v); } + +static inline void bs_write_u8(bs_t* b, uint32_t v) +{ +#ifdef FAST_U8 + if (b->bits_left == 8 && ! bs_eof(b)) // can do fast write + { + b->p[0] = v; + b->p++; + return; + } +#endif + bs_write_u(b, 8, v); +} + +static inline void bs_write_ue(bs_t* b, uint32_t v) +{ + static const int len_table[256] = + { + 1, + 1, + 2,2, + 3,3,3,3, + 4,4,4,4,4,4,4,4, + 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, + 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, + 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, + }; + + int len; + + if (v == 0) + { + bs_write_u1(b, 1); + } + else + { + v++; + + if (v >= 0x01000000) + { + len = 24 + len_table[ v >> 24 ]; + } + else if(v >= 0x00010000) + { + len = 16 + len_table[ v >> 16 ]; + } + else if(v >= 0x00000100) + { + len = 8 + len_table[ v >> 8 ]; + } + else + { + len = len_table[ v ]; + } + + bs_write_u(b, 2*len-1, v); + } +} + +static inline void bs_write_se(bs_t* b, int32_t v) +{ + if (v <= 0) + { + bs_write_ue(b, -v*2); + } + else + { + bs_write_ue(b, v*2 - 1); + } +} + +static inline int bs_read_bytes(bs_t* b, uint8_t* buf, int len) +{ + int actual_len = len; + if (b->end - b->p < actual_len) { actual_len = b->end - b->p; } + if (actual_len < 0) { actual_len = 0; } + memcpy(buf, b->p, actual_len); + if (len < 0) { len = 0; } + b->p += len; + return actual_len; +} + +static inline int bs_write_bytes(bs_t* b, uint8_t* buf, int len) +{ + int actual_len = len; + if (b->end - b->p < actual_len) { actual_len = b->end - b->p; } + if (actual_len < 0) { actual_len = 0; } + memcpy(b->p, buf, actual_len); + if (len < 0) { len = 0; } + b->p += len; + return actual_len; +} + +static inline int bs_skip_bytes(bs_t* b, int len) +{ + int actual_len = len; + if (b->end - b->p < actual_len) { actual_len = b->end - b->p; } + if (actual_len < 0) { actual_len = 0; } + if (len < 0) { len = 0; } + b->p += len; + return actual_len; +} + +static inline uint32_t bs_next_bits(bs_t* bs, int nbits) +{ + bs_t b; + bs_clone(&b,bs); + return bs_read_u(&b, nbits); +} + +static inline uint64_t bs_next_bytes(bs_t* bs, int nbytes) +{ + int i = 0; + uint64_t val = 0; + + if ( (nbytes > 8) || (nbytes < 1) ) { return 0; } + if (bs->p + nbytes > bs->end) { return 0; } + + for ( i = 0; i < nbytes; i++ ) { val = ( val << 8 ) | bs->p[i]; } + return val; +} + +#define bs_print_state(b) fprintf( stderr, "%s:%d@%s: b->p=0x%02hhX, b->left = %d\n", __FILE__, __LINE__, __FUNCTION__, *b->p, b->bits_left ) + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/utils/h264_stream.c b/src/utils/h264_stream.c new file mode 100644 index 000000000..4538208ac --- /dev/null +++ b/src/utils/h264_stream.c @@ -0,0 +1,426 @@ +/* + * h264bitstream - a library for reading and writing H.264 video + * Copyright (C) 2005-2007 Auroras Entertainment, LLC + * Copyright (C) 2008-2011 Avail-TVN + * + * Written by Alex Izvorski and Alex Giladi + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include + +#include "h264_stream.h" + +/***************************** reading ******************************/ + +/** + Convert NAL data (Annex B format) to RBSP data. + The size of rbsp_buf must be the same as size of the nal_buf to guarantee the output will fit. + If that is not true, output may be truncated and an error will be returned. + Additionally, certain byte sequences in the input nal_buf are not allowed in the spec and also cause the conversion to fail and an error to be returned. + @param[in] nal_buf the nal data + @param[in,out] nal_size as input, pointer to the size of the nal data; as output, filled in with the actual size of the nal data + @param[in,out] rbsp_buf allocated memory in which to put the rbsp data + @param[in,out] rbsp_size as input, pointer to the maximum size of the rbsp data; as output, filled in with the actual size of rbsp data + @return actual size of rbsp data, or -1 on error + */ +// 7.3.1 NAL unit syntax +// 7.4.1.1 Encapsulation of an SODB within an RBSP +int nal_to_rbsp(const uint8_t* nal_buf, int* nal_size, uint8_t* rbsp_buf, int* rbsp_size) +{ + int i; + int j = 0; + int count = 0; + + for( i = 1; i < *nal_size; i++ ) + { + // in NAL unit, 0x000000, 0x000001 or 0x000002 shall not occur at any byte-aligned position + if( ( count == 2 ) && ( nal_buf[i] < 0x03) ) + { + return -1; + } + + if( ( count == 2 ) && ( nal_buf[i] == 0x03) ) + { + // check the 4th byte after 0x000003, except when cabac_zero_word is used, in which case the last three bytes of this NAL unit must be 0x000003 + if((i < *nal_size - 1) && (nal_buf[i+1] > 0x03)) + { + return -1; + } + + // if cabac_zero_word is used, the final byte of this NAL unit(0x03) is discarded, and the last two bytes of RBSP must be 0x0000 + if(i == *nal_size - 1) + { + break; + } + + i++; + count = 0; + } + + if ( j >= *rbsp_size ) + { + // error, not enough space + return -1; + } + + rbsp_buf[j] = nal_buf[i]; + if(nal_buf[i] == 0x00) + { + count++; + } + else + { + count = 0; + } + j++; + } + + *nal_size = i; + *rbsp_size = j; + return j; +} + +//7.3.2.1 Sequence parameter set RBSP syntax +int read_seq_parameter_set_rbsp(sps_t* sps, bs_t* b) { + + int i; + + memset(sps, 0, sizeof(sps_t)); + + sps->profile_idc = bs_read_u8(b); + sps->constraint_set0_flag = bs_read_u1(b); + sps->constraint_set1_flag = bs_read_u1(b); + sps->constraint_set2_flag = bs_read_u1(b); + sps->constraint_set3_flag = bs_read_u1(b); + sps->constraint_set4_flag = bs_read_u1(b); + sps->constraint_set5_flag = bs_read_u1(b); + sps->reserved_zero_2bits = bs_read_u(b,2); /* all 0's */ + sps->level_idc = bs_read_u8(b); + sps->seq_parameter_set_id = bs_read_ue(b); + + sps->chroma_format_idc = 1; + if( sps->profile_idc == 100 || sps->profile_idc == 110 || + sps->profile_idc == 122 || sps->profile_idc == 144 ) + { + sps->chroma_format_idc = bs_read_ue(b); + if( sps->chroma_format_idc == 3 ) + { + sps->residual_colour_transform_flag = bs_read_u1(b); + } + sps->bit_depth_luma_minus8 = bs_read_ue(b); + sps->bit_depth_chroma_minus8 = bs_read_ue(b); + sps->qpprime_y_zero_transform_bypass_flag = bs_read_u1(b); + sps->seq_scaling_matrix_present_flag = bs_read_u1(b); + if( sps->seq_scaling_matrix_present_flag ) + { + for( i = 0; i < 8; i++ ) + { + sps->seq_scaling_list_present_flag[ i ] = bs_read_u1(b); + if( sps->seq_scaling_list_present_flag[ i ] ) + { + if( i < 6 ) + { + read_scaling_list( b, sps->ScalingList4x4[ i ], 16, + sps->UseDefaultScalingMatrix4x4Flag[ i ]); + } + else + { + read_scaling_list( b, sps->ScalingList8x8[ i - 6 ], 64, + sps->UseDefaultScalingMatrix8x8Flag[ i - 6 ] ); + } + } + } + } + } + sps->log2_max_frame_num_minus4 = bs_read_ue(b); + sps->pic_order_cnt_type = bs_read_ue(b); + if( sps->pic_order_cnt_type == 0 ) + { + sps->log2_max_pic_order_cnt_lsb_minus4 = bs_read_ue(b); + } + else if( sps->pic_order_cnt_type == 1 ) + { + sps->delta_pic_order_always_zero_flag = bs_read_u1(b); + sps->offset_for_non_ref_pic = bs_read_se(b); + sps->offset_for_top_to_bottom_field = bs_read_se(b); + sps->num_ref_frames_in_pic_order_cnt_cycle = bs_read_ue(b); + for( i = 0; i < sps->num_ref_frames_in_pic_order_cnt_cycle; i++ ) + { + sps->offset_for_ref_frame[ i ] = bs_read_se(b); + } + } + sps->num_ref_frames = bs_read_ue(b); + sps->gaps_in_frame_num_value_allowed_flag = bs_read_u1(b); + sps->pic_width_in_mbs_minus1 = bs_read_ue(b); + sps->pic_height_in_map_units_minus1 = bs_read_ue(b); + sps->frame_mbs_only_flag = bs_read_u1(b); + if( !sps->frame_mbs_only_flag ) + { + sps->mb_adaptive_frame_field_flag = bs_read_u1(b); + } + sps->direct_8x8_inference_flag = bs_read_u1(b); + sps->frame_cropping_flag = bs_read_u1(b); + if( sps->frame_cropping_flag ) + { + sps->frame_crop_left_offset = bs_read_ue(b); + sps->frame_crop_right_offset = bs_read_ue(b); + sps->frame_crop_top_offset = bs_read_ue(b); + sps->frame_crop_bottom_offset = bs_read_ue(b); + } + sps->vui_parameters_present_flag = bs_read_u1(b); + if( sps->vui_parameters_present_flag ) + { + read_vui_parameters(sps, b); + } + read_rbsp_trailing_bits(b); + + return 0; +} + + +//7.3.2.1.1 Scaling list syntax +void read_scaling_list(bs_t* b, int* scalingList, int sizeOfScalingList, int useDefaultScalingMatrixFlag ) +{ + int j; + if(scalingList == NULL) + { + return; + } + + int lastScale = 8; + int nextScale = 8; + for( j = 0; j < sizeOfScalingList; j++ ) + { + if( nextScale != 0 ) + { + int delta_scale = bs_read_se(b); + nextScale = ( lastScale + delta_scale + 256 ) % 256; + useDefaultScalingMatrixFlag = ( j == 0 && nextScale == 0 ); + } + scalingList[ j ] = ( nextScale == 0 ) ? lastScale : nextScale; + lastScale = scalingList[ j ]; + } +} + +//Appendix E.1.1 VUI parameters syntax +void read_vui_parameters(sps_t* sps, bs_t* b) +{ + + sps->vui.aspect_ratio_info_present_flag = bs_read_u1(b); + if( sps->vui.aspect_ratio_info_present_flag ) + { + sps->vui.aspect_ratio_idc = bs_read_u8(b); + if( sps->vui.aspect_ratio_idc == SAR_Extended ) + { + sps->vui.sar_width = bs_read_u(b,16); + sps->vui.sar_height = bs_read_u(b,16); + } + } + sps->vui.overscan_info_present_flag = bs_read_u1(b); + if( sps->vui.overscan_info_present_flag ) + { + sps->vui.overscan_appropriate_flag = bs_read_u1(b); + } + sps->vui.video_signal_type_present_flag = bs_read_u1(b); + if( sps->vui.video_signal_type_present_flag ) + { + sps->vui.video_format = bs_read_u(b,3); + sps->vui.video_full_range_flag = bs_read_u1(b); + sps->vui.colour_description_present_flag = bs_read_u1(b); + if( sps->vui.colour_description_present_flag ) + { + sps->vui.colour_primaries = bs_read_u8(b); + sps->vui.transfer_characteristics = bs_read_u8(b); + sps->vui.matrix_coefficients = bs_read_u8(b); + } + } + sps->vui.chroma_loc_info_present_flag = bs_read_u1(b); + if( sps->vui.chroma_loc_info_present_flag ) + { + sps->vui.chroma_sample_loc_type_top_field = bs_read_ue(b); + sps->vui.chroma_sample_loc_type_bottom_field = bs_read_ue(b); + } + sps->vui.timing_info_present_flag = bs_read_u1(b); + if( sps->vui.timing_info_present_flag ) + { + sps->vui.num_units_in_tick = bs_read_u(b,32); + sps->vui.time_scale = bs_read_u(b,32); + sps->vui.fixed_frame_rate_flag = bs_read_u1(b); + } + sps->vui.nal_hrd_parameters_present_flag = bs_read_u1(b); + if( sps->vui.nal_hrd_parameters_present_flag ) + { + read_hrd_parameters(sps, b); + } + sps->vui.vcl_hrd_parameters_present_flag = bs_read_u1(b); + if( sps->vui.vcl_hrd_parameters_present_flag ) + { + read_hrd_parameters(sps, b); + } + if( sps->vui.nal_hrd_parameters_present_flag || sps->vui.vcl_hrd_parameters_present_flag ) + { + sps->vui.low_delay_hrd_flag = bs_read_u1(b); + } + sps->vui.pic_struct_present_flag = bs_read_u1(b); + sps->vui.bitstream_restriction_flag = bs_read_u1(b); + if( sps->vui.bitstream_restriction_flag ) + { + sps->vui.motion_vectors_over_pic_boundaries_flag = bs_read_u1(b); + sps->vui.max_bytes_per_pic_denom = bs_read_ue(b); + sps->vui.max_bits_per_mb_denom = bs_read_ue(b); + sps->vui.log2_max_mv_length_horizontal = bs_read_ue(b); + sps->vui.log2_max_mv_length_vertical = bs_read_ue(b); + sps->vui.num_reorder_frames = bs_read_ue(b); + sps->vui.max_dec_frame_buffering = bs_read_ue(b); + } +} + + +//Appendix E.1.2 HRD parameters syntax +void read_hrd_parameters(sps_t* sps, bs_t* b) +{ + int SchedSelIdx; + + sps->hrd.cpb_cnt_minus1 = bs_read_ue(b); + sps->hrd.bit_rate_scale = bs_read_u(b,4); + sps->hrd.cpb_size_scale = bs_read_u(b,4); + for( SchedSelIdx = 0; SchedSelIdx <= sps->hrd.cpb_cnt_minus1; SchedSelIdx++ ) + { + sps->hrd.bit_rate_value_minus1[ SchedSelIdx ] = bs_read_ue(b); + sps->hrd.cpb_size_value_minus1[ SchedSelIdx ] = bs_read_ue(b); + sps->hrd.cbr_flag[ SchedSelIdx ] = bs_read_u1(b); + } + sps->hrd.initial_cpb_removal_delay_length_minus1 = bs_read_u(b,5); + sps->hrd.cpb_removal_delay_length_minus1 = bs_read_u(b,5); + sps->hrd.dpb_output_delay_length_minus1 = bs_read_u(b,5); + sps->hrd.time_offset_length = bs_read_u(b,5); +} + +//7.3.2.11 RBSP trailing bits syntax +void read_rbsp_trailing_bits(bs_t* b) +{ + int rbsp_stop_one_bit = bs_read_u1( b ); // equal to 1 + + while( !bs_byte_aligned(b) ) + { + int rbsp_alignment_zero_bit = bs_read_u1( b ); // equal to 0 + } +} + +/***************************** debug ******************************/ + +void debug_sps(sps_t* sps) +{ + printf("======= SPS =======\n"); + printf(" profile_idc : %d \n", sps->profile_idc ); + printf(" constraint_set0_flag : %d \n", sps->constraint_set0_flag ); + printf(" constraint_set1_flag : %d \n", sps->constraint_set1_flag ); + printf(" constraint_set2_flag : %d \n", sps->constraint_set2_flag ); + printf(" constraint_set3_flag : %d \n", sps->constraint_set3_flag ); + printf(" constraint_set4_flag : %d \n", sps->constraint_set4_flag ); + printf(" constraint_set5_flag : %d \n", sps->constraint_set5_flag ); + printf(" reserved_zero_2bits : %d \n", sps->reserved_zero_2bits ); + printf(" level_idc : %d \n", sps->level_idc ); + printf(" seq_parameter_set_id : %d \n", sps->seq_parameter_set_id ); + printf(" chroma_format_idc : %d \n", sps->chroma_format_idc ); + printf(" residual_colour_transform_flag : %d \n", sps->residual_colour_transform_flag ); + printf(" bit_depth_luma_minus8 : %d \n", sps->bit_depth_luma_minus8 ); + printf(" bit_depth_chroma_minus8 : %d \n", sps->bit_depth_chroma_minus8 ); + printf(" qpprime_y_zero_transform_bypass_flag : %d \n", sps->qpprime_y_zero_transform_bypass_flag ); + printf(" seq_scaling_matrix_present_flag : %d \n", sps->seq_scaling_matrix_present_flag ); + // int seq_scaling_list_present_flag[8]; + // void* ScalingList4x4[6]; + // int UseDefaultScalingMatrix4x4Flag[6]; + // void* ScalingList8x8[2]; + // int UseDefaultScalingMatrix8x8Flag[2]; + printf(" log2_max_frame_num_minus4 : %d \n", sps->log2_max_frame_num_minus4 ); + printf(" pic_order_cnt_type : %d \n", sps->pic_order_cnt_type ); + printf(" log2_max_pic_order_cnt_lsb_minus4 : %d \n", sps->log2_max_pic_order_cnt_lsb_minus4 ); + printf(" delta_pic_order_always_zero_flag : %d \n", sps->delta_pic_order_always_zero_flag ); + printf(" offset_for_non_ref_pic : %d \n", sps->offset_for_non_ref_pic ); + printf(" offset_for_top_to_bottom_field : %d \n", sps->offset_for_top_to_bottom_field ); + printf(" num_ref_frames_in_pic_order_cnt_cycle : %d \n", sps->num_ref_frames_in_pic_order_cnt_cycle ); + // int offset_for_ref_frame[256]; + printf(" num_ref_frames : %d \n", sps->num_ref_frames ); + printf(" gaps_in_frame_num_value_allowed_flag : %d \n", sps->gaps_in_frame_num_value_allowed_flag ); + printf(" pic_width_in_mbs_minus1 : %d \n", sps->pic_width_in_mbs_minus1 ); + printf(" pic_height_in_map_units_minus1 : %d \n", sps->pic_height_in_map_units_minus1 ); + printf(" frame_mbs_only_flag : %d \n", sps->frame_mbs_only_flag ); + printf(" mb_adaptive_frame_field_flag : %d \n", sps->mb_adaptive_frame_field_flag ); + printf(" direct_8x8_inference_flag : %d \n", sps->direct_8x8_inference_flag ); + printf(" frame_cropping_flag : %d \n", sps->frame_cropping_flag ); + printf(" frame_crop_left_offset : %d \n", sps->frame_crop_left_offset ); + printf(" frame_crop_right_offset : %d \n", sps->frame_crop_right_offset ); + printf(" frame_crop_top_offset : %d \n", sps->frame_crop_top_offset ); + printf(" frame_crop_bottom_offset : %d \n", sps->frame_crop_bottom_offset ); + printf(" vui_parameters_present_flag : %d \n", sps->vui_parameters_present_flag ); + + printf("=== VUI ===\n"); + printf(" aspect_ratio_info_present_flag : %d \n", sps->vui.aspect_ratio_info_present_flag ); + printf(" aspect_ratio_idc : %d \n", sps->vui.aspect_ratio_idc ); + printf(" sar_width : %d \n", sps->vui.sar_width ); + printf(" sar_height : %d \n", sps->vui.sar_height ); + printf(" overscan_info_present_flag : %d \n", sps->vui.overscan_info_present_flag ); + printf(" overscan_appropriate_flag : %d \n", sps->vui.overscan_appropriate_flag ); + printf(" video_signal_type_present_flag : %d \n", sps->vui.video_signal_type_present_flag ); + printf(" video_format : %d \n", sps->vui.video_format ); + printf(" video_full_range_flag : %d \n", sps->vui.video_full_range_flag ); + printf(" colour_description_present_flag : %d \n", sps->vui.colour_description_present_flag ); + printf(" colour_primaries : %d \n", sps->vui.colour_primaries ); + printf(" transfer_characteristics : %d \n", sps->vui.transfer_characteristics ); + printf(" matrix_coefficients : %d \n", sps->vui.matrix_coefficients ); + printf(" chroma_loc_info_present_flag : %d \n", sps->vui.chroma_loc_info_present_flag ); + printf(" chroma_sample_loc_type_top_field : %d \n", sps->vui.chroma_sample_loc_type_top_field ); + printf(" chroma_sample_loc_type_bottom_field : %d \n", sps->vui.chroma_sample_loc_type_bottom_field ); + printf(" timing_info_present_flag : %d \n", sps->vui.timing_info_present_flag ); + printf(" num_units_in_tick : %d \n", sps->vui.num_units_in_tick ); + printf(" time_scale : %d \n", sps->vui.time_scale ); + printf(" fixed_frame_rate_flag : %d \n", sps->vui.fixed_frame_rate_flag ); + printf(" nal_hrd_parameters_present_flag : %d \n", sps->vui.nal_hrd_parameters_present_flag ); + printf(" vcl_hrd_parameters_present_flag : %d \n", sps->vui.vcl_hrd_parameters_present_flag ); + printf(" low_delay_hrd_flag : %d \n", sps->vui.low_delay_hrd_flag ); + printf(" pic_struct_present_flag : %d \n", sps->vui.pic_struct_present_flag ); + printf(" bitstream_restriction_flag : %d \n", sps->vui.bitstream_restriction_flag ); + printf(" motion_vectors_over_pic_boundaries_flag : %d \n", sps->vui.motion_vectors_over_pic_boundaries_flag ); + printf(" max_bytes_per_pic_denom : %d \n", sps->vui.max_bytes_per_pic_denom ); + printf(" max_bits_per_mb_denom : %d \n", sps->vui.max_bits_per_mb_denom ); + printf(" log2_max_mv_length_horizontal : %d \n", sps->vui.log2_max_mv_length_horizontal ); + printf(" log2_max_mv_length_vertical : %d \n", sps->vui.log2_max_mv_length_vertical ); + printf(" num_reorder_frames : %d \n", sps->vui.num_reorder_frames ); + printf(" max_dec_frame_buffering : %d \n", sps->vui.max_dec_frame_buffering ); + + printf("=== HRD ===\n"); + printf(" cpb_cnt_minus1 : %d \n", sps->hrd.cpb_cnt_minus1 ); + printf(" bit_rate_scale : %d \n", sps->hrd.bit_rate_scale ); + printf(" cpb_size_scale : %d \n", sps->hrd.cpb_size_scale ); + int SchedSelIdx; + for( SchedSelIdx = 0; SchedSelIdx <= sps->hrd.cpb_cnt_minus1; SchedSelIdx++ ) + { + printf(" bit_rate_value_minus1[%d] : %d \n", SchedSelIdx, sps->hrd.bit_rate_value_minus1[SchedSelIdx] ); // up to cpb_cnt_minus1, which is <= 31 + printf(" cpb_size_value_minus1[%d] : %d \n", SchedSelIdx, sps->hrd.cpb_size_value_minus1[SchedSelIdx] ); + printf(" cbr_flag[%d] : %d \n", SchedSelIdx, sps->hrd.cbr_flag[SchedSelIdx] ); + } + printf(" initial_cpb_removal_delay_length_minus1 : %d \n", sps->hrd.initial_cpb_removal_delay_length_minus1 ); + printf(" cpb_removal_delay_length_minus1 : %d \n", sps->hrd.cpb_removal_delay_length_minus1 ); + printf(" dpb_output_delay_length_minus1 : %d \n", sps->hrd.dpb_output_delay_length_minus1 ); + printf(" time_offset_length : %d \n", sps->hrd.time_offset_length ); +} + + + diff --git a/src/utils/h264_stream.h b/src/utils/h264_stream.h new file mode 100644 index 000000000..99e134e4a --- /dev/null +++ b/src/utils/h264_stream.h @@ -0,0 +1,165 @@ +/* + * h264bitstream - a library for reading and writing H.264 video + * Copyright (C) 2005-2007 Auroras Entertainment, LLC + * Copyright (C) 2008-2011 Avail-TVN + * + * Written by Alex Izvorski and Alex Giladi + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef _H264_STREAM_H +#define _H264_STREAM_H 1 + +#include +#include +#include + +#include "bs.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + Sequence Parameter Set + @see 7.3.2.1 Sequence parameter set RBSP syntax + @see read_seq_parameter_set_rbsp + @see write_seq_parameter_set_rbsp + @see debug_sps +*/ +typedef struct +{ + int profile_idc; + int constraint_set0_flag; + int constraint_set1_flag; + int constraint_set2_flag; + int constraint_set3_flag; + int constraint_set4_flag; + int constraint_set5_flag; + int reserved_zero_2bits; + int level_idc; + int seq_parameter_set_id; + int chroma_format_idc; + int residual_colour_transform_flag; + int bit_depth_luma_minus8; + int bit_depth_chroma_minus8; + int qpprime_y_zero_transform_bypass_flag; + int seq_scaling_matrix_present_flag; + int seq_scaling_list_present_flag[8]; + int* ScalingList4x4[6]; + int UseDefaultScalingMatrix4x4Flag[6]; + int* ScalingList8x8[2]; + int UseDefaultScalingMatrix8x8Flag[2]; + int log2_max_frame_num_minus4; + int pic_order_cnt_type; + int log2_max_pic_order_cnt_lsb_minus4; + int delta_pic_order_always_zero_flag; + int offset_for_non_ref_pic; + int offset_for_top_to_bottom_field; + int num_ref_frames_in_pic_order_cnt_cycle; + int offset_for_ref_frame[256]; + int num_ref_frames; + int gaps_in_frame_num_value_allowed_flag; + int pic_width_in_mbs_minus1; + int pic_height_in_map_units_minus1; + int frame_mbs_only_flag; + int mb_adaptive_frame_field_flag; + int direct_8x8_inference_flag; + int frame_cropping_flag; + int frame_crop_left_offset; + int frame_crop_right_offset; + int frame_crop_top_offset; + int frame_crop_bottom_offset; + int vui_parameters_present_flag; + + struct + { + int aspect_ratio_info_present_flag; + int aspect_ratio_idc; + int sar_width; + int sar_height; + int overscan_info_present_flag; + int overscan_appropriate_flag; + int video_signal_type_present_flag; + int video_format; + int video_full_range_flag; + int colour_description_present_flag; + int colour_primaries; + int transfer_characteristics; + int matrix_coefficients; + int chroma_loc_info_present_flag; + int chroma_sample_loc_type_top_field; + int chroma_sample_loc_type_bottom_field; + int timing_info_present_flag; + int num_units_in_tick; + int time_scale; + int fixed_frame_rate_flag; + int nal_hrd_parameters_present_flag; + int vcl_hrd_parameters_present_flag; + int low_delay_hrd_flag; + int pic_struct_present_flag; + int bitstream_restriction_flag; + int motion_vectors_over_pic_boundaries_flag; + int max_bytes_per_pic_denom; + int max_bits_per_mb_denom; + int log2_max_mv_length_horizontal; + int log2_max_mv_length_vertical; + int num_reorder_frames; + int max_dec_frame_buffering; + } vui; + + struct + { + int cpb_cnt_minus1; + int bit_rate_scale; + int cpb_size_scale; + int bit_rate_value_minus1[32]; // up to cpb_cnt_minus1, which is <= 31 + int cpb_size_value_minus1[32]; + int cbr_flag[32]; + int initial_cpb_removal_delay_length_minus1; + int cpb_removal_delay_length_minus1; + int dpb_output_delay_length_minus1; + int time_offset_length; + } hrd; + +} sps_t; + +/** + H264 stream + Contains data structures for all NAL types that can be handled by this library. + When reading, data is read into those, and when writing it is written from those. + The reason why they are all contained in one place is that some of them depend on others, we need to + have all of them available to read or write correctly. + */ + +int nal_to_rbsp(const uint8_t* nal_buf, int* nal_size, uint8_t* rbsp_buf, int* rbsp_size); + +int read_seq_parameter_set_rbsp(sps_t* h, bs_t* b); +void read_scaling_list(bs_t* b, int* scalingList, int sizeOfScalingList, int useDefaultScalingMatrixFlag ); +void read_vui_parameters(sps_t* h, bs_t* b); +void read_hrd_parameters(sps_t* h, bs_t* b); + +void read_rbsp_trailing_bits(bs_t* b); + +void debug_sps(sps_t* sps); + +#define SAR_Extended 255 + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/video_capture/rtsp.c b/src/video_capture/rtsp.c index d588664c8..3ce9693bb 100644 --- a/src/video_capture/rtsp.c +++ b/src/video_capture/rtsp.c @@ -58,6 +58,7 @@ #include "rtp/rtp.h" #include "rtp/rtp_callback.h" #include "rtp/rtpdec_h264.h" +#include "rtsp/rtsp_utils.h" #include "video_decompress.h" #include "video_decompress/libavcodec.h" @@ -76,61 +77,58 @@ #define VERSION_STR "V1.0" //TODO set lower initial video recv buffer size (to find the minimal?) -#define INITIAL_VIDEO_RECV_BUFFER_SIZE ((0.1*1920*1080)*110/100) //command line net.core setup: sysctl -w net.core.rmem_max=9123840 +#define DEFAULT_VIDEO_FRAME_WIDTH 1920 +#define DEFAULT_VIDEO_FRAME_HEIGHT 1080 +#define INITIAL_VIDEO_RECV_BUFFER_SIZE ((0.1*DEFAULT_VIDEO_FRAME_WIDTH*DEFAULT_VIDEO_FRAME_HEIGHT)*110/100) //command line net.core setup: sysctl -w net.core.rmem_max=9123840 + /* error handling macros */ #define my_curl_easy_setopt(A, B, C) \ if ((res = curl_easy_setopt((A), (B), (C))) != CURLE_OK){ \ -fprintf(stderr, "[rtsp error] curl_easy_setopt(%s, %s, %s) failed: %d\n", #A, #B, #C, res); \ -printf("[rtsp error] could not configure rtsp capture properly, \n\t\tplease check your parameters. \nExiting...\n\n"); \ -exit(0); \ -} + fprintf(stderr, "[rtsp error] curl_easy_setopt(%s, %s, %s) failed: %d\n", #A, #B, #C, res); \ + printf("[rtsp error] could not configure rtsp capture properly, \n\t\tplease check your parameters. \nExiting...\n\n"); \ + return NULL; \ + } #define my_curl_easy_perform(A) \ if ((res = curl_easy_perform((A))) != CURLE_OK){ \ -fprintf(stderr, "[rtsp error] curl_easy_perform(%s) failed: %d\n", #A, res); \ -printf("[rtsp error] could not configure rtsp capture properly, \n\t\tplease check your parameters. \nExiting...\n\n"); \ -exit(0); \ -} + fprintf(stderr, "[rtsp error] curl_easy_perform(%s) failed: %d\n", #A, res); \ + printf("[rtsp error] could not configure rtsp capture properly, \n\t\tplease check your parameters. \nExiting...\n\n"); \ + return NULL; \ + } /* send RTSP GET_PARAMETERS request */ -static void +static int rtsp_get_parameters(CURL *curl, const char *uri); /* send RTSP OPTIONS request */ -static void +static int rtsp_options(CURL *curl, const char *uri); /* send RTSP DESCRIBE request and write sdp response to a file */ -static void +static int rtsp_describe(CURL *curl, const char *uri, const char *sdp_filename); /* send RTSP SETUP request */ -static void +static int rtsp_setup(CURL *curl, const char *uri, const char *transport); /* send RTSP PLAY request */ -static void +static int rtsp_play(CURL *curl, const char *uri, const char *range); /* send RTSP TEARDOWN request */ -static void +static int rtsp_teardown(CURL *curl, const char *uri); /* convert url into an sdp filename */ static void get_sdp_filename(const char *url, char *sdp_filename); -/* scan sdp file for media control attribute */ -static void -get_media_control_attribute(const char *sdp_filename, char *control); - -/* scan sdp file for incoming codec */ static int -set_codec_attribute_from_incoming_media(const char *sdp_filename, void *state); +get_nals(const char *sdp_filename, char *nals, int *width, int *height); -static int -get_nals(const char *sdp_filename, char *nals); +void setup_codecs_and_controls_from_sdp(const char *sdp_filename, void *state); static int init_rtsp(char* rtsp_uri, int rtsp_port, void *state, char* nals); @@ -144,38 +142,48 @@ vidcap_rtsp_thread(void *args); static void show_help(void); +void getNewLine(const char* buffer, int* i, char* line); + +void setup_codecs_and_controls_from_sdp(const char *sdp_filename, void *state); + void rtsp_keepalive(void *state); -FILE *F_video_rtsp = NULL; +int decode_frame_by_pt(struct coded_data *cdata, void *decode_data); + +static const uint8_t start_sequence[] = { 0, 0, 0, 1 }; + /** * @struct rtsp_state */ -struct rtsp_state { - char *nals; - int nals_size; - char *data; //nals + data +struct video_rtsp_state { uint32_t *in_codec; + char *codec; + struct timeval t0, t; int frames; struct video_frame *frame; struct tile *tile; - struct audio_frame audio; - int width; - int height; - struct std_frame_received *rx_data; + //struct std_frame_received *rx_data; bool new_frame; bool decompress; bool grab; + struct state_decompress *sd; + struct video_desc des; + char * out_frame; + + int port; + float fps; + char *control; + struct rtp *device; struct pdb *participants; struct pdb_e *cp; double rtcp_bw; int ttl; - char *addr; char *mcast_if; struct timeval curr_time; struct timeval timeout; @@ -184,28 +192,67 @@ struct rtsp_state { int required_connections; uint32_t timestamp; - int play_audio_frame; + pthread_t vrtsp_thread_id; //the worker_id - struct timeval last_audio_time; - unsigned int grab_audio:1; - - pthread_t rtsp_thread_id; //the worker_id pthread_mutex_t lock; pthread_cond_t worker_cv; volatile bool worker_waiting; pthread_cond_t boss_cv; volatile bool boss_waiting; +}; - volatile bool should_exit; +struct audio_rtsp_state { + struct audio_frame audio; + int play_audio_frame; - struct state_decompress *sd; - struct video_desc des; - char * out_frame; + char *codec; + + struct timeval last_audio_time; + unsigned int grab_audio:1; - CURL *curl; - char *uri; int port; float fps; + + char *control; + + struct rtp *device; + struct pdb *participants; + struct pdb_e *cp; + double rtcp_bw; + int ttl; + char *mcast_if; + struct timeval curr_time; + struct timeval timeout; + struct timeval prev_time; + struct timeval start_time; + int required_connections; + uint32_t timestamp; + + pthread_t artsp_thread_id; //the worker_id + pthread_mutex_t lock; + pthread_cond_t worker_cv; + volatile bool worker_waiting; + pthread_cond_t boss_cv; + volatile bool boss_waiting; +}; + +struct rtsp_state { + CURL *curl; + char *uri; + rtps_types_t avType; + char *addr; + char *sdp; + + volatile bool should_exit; + struct audio_rtsp_state *artsp_state; + struct video_rtsp_state *vrtsp_state; + + pthread_t keep_alive_rtsp_thread_id; //the worker_id + pthread_mutex_t lock; + pthread_cond_t worker_cv; + volatile bool worker_waiting; + pthread_cond_t boss_cv; + volatile bool boss_waiting; }; static void @@ -221,14 +268,40 @@ show_help() { } void -rtsp_keepalive(void *state) { +rtsp_keepalive_video(void *state) { struct rtsp_state *s; s = (struct rtsp_state *) state; struct timeval now; gettimeofday(&now, NULL); - if (tv_diff(now, s->prev_time) >= 20) { - rtsp_get_parameters(s->curl, s->uri); - gettimeofday(&s->prev_time, NULL); + if (tv_diff(now, s->vrtsp_state->prev_time) >= 20) { + if(rtsp_get_parameters(s->curl, s->uri)==0){ + s->should_exit = TRUE; + vidcap_rtsp_done(s); + exit(0); + } + gettimeofday(&s->vrtsp_state->prev_time, NULL); + } +} + +static void * +keep_alive_thread(void *arg){ + struct rtsp_state *s; + s = (struct rtsp_state *) arg; + while (!s->should_exit) { + rtsp_keepalive_video(s); + } +} + +int decode_frame_by_pt(struct coded_data *cdata, void *decode_data) { + rtp_packet *pckt = NULL; + pckt = cdata->data; + + switch(pckt->pt){ + case PT_H264: + return decode_frame_h264(cdata,decode_data); + default: + error_msg("Wrong Payload type: %u\n", pckt->pt); + return FALSE; } } @@ -237,50 +310,45 @@ vidcap_rtsp_thread(void *arg) { struct rtsp_state *s; s = (struct rtsp_state *) arg; - gettimeofday(&s->start_time, NULL); - gettimeofday(&s->prev_time, NULL); + gettimeofday(&s->vrtsp_state->start_time, NULL); + gettimeofday(&s->vrtsp_state->prev_time, NULL); while (!s->should_exit) { - gettimeofday(&s->curr_time, NULL); - s->timestamp = tv_diff(s->curr_time, s->start_time) * 90000; + gettimeofday(&s->vrtsp_state->curr_time, NULL); + s->vrtsp_state->timestamp = tv_diff(s->vrtsp_state->curr_time, s->vrtsp_state->start_time) * 90000; - rtsp_keepalive(s); + rtp_update(s->vrtsp_state->device, s->vrtsp_state->curr_time); - rtp_update(s->device, s->curr_time); - //TODO no need of rtcp communication between ug and rtsp server? - //rtp_send_ctrl(s->device, s->timestamp, 0, s->curr_time); + s->vrtsp_state->timeout.tv_sec = 0; + s->vrtsp_state->timeout.tv_usec = 10000; - s->timeout.tv_sec = 0; - s->timeout.tv_usec = 10000; - - if (!rtp_recv_r(s->device, &s->timeout, s->timestamp)) { + if (!rtp_recv_r(s->vrtsp_state->device, &s->vrtsp_state->timeout, s->vrtsp_state->timestamp)) { pdb_iter_t it; - s->cp = pdb_iter_init(s->participants, &it); + s->vrtsp_state->cp = pdb_iter_init(s->vrtsp_state->participants, &it); - while (s->cp != NULL) { - if (pthread_mutex_trylock(&s->lock) == 0) { + while (s->vrtsp_state->cp != NULL) { + if (pthread_mutex_trylock(&s->vrtsp_state->lock) == 0) { { - if(s->grab){ + if(s->vrtsp_state->grab){ - while (s->new_frame && !s->should_exit) { - s->worker_waiting = true; - pthread_cond_wait(&s->worker_cv, &s->lock); - s->worker_waiting = false; + while (s->vrtsp_state->new_frame && !s->should_exit) { + s->vrtsp_state->worker_waiting = true; + pthread_cond_wait(&s->vrtsp_state->worker_cv, &s->vrtsp_state->lock); + s->vrtsp_state->worker_waiting = false; } - - if (pbuf_decode(s->cp->playout_buffer, s->curr_time, - decode_frame_h264, s->rx_data)) + if (pbuf_decode(s->vrtsp_state->cp->playout_buffer, s->vrtsp_state->curr_time, + decode_frame_by_pt, s->vrtsp_state->frame)) { - s->new_frame = true; + s->vrtsp_state->new_frame = true; } - if (s->boss_waiting) - pthread_cond_signal(&s->boss_cv); + if (s->vrtsp_state->boss_waiting) + pthread_cond_signal(&s->vrtsp_state->boss_cv); } } - pthread_mutex_unlock(&s->lock); + pthread_mutex_unlock(&s->vrtsp_state->lock); } - pbuf_remove(s->cp->playout_buffer, s->curr_time); - s->cp = pdb_iter_next(&it); + pbuf_remove(s->vrtsp_state->cp->playout_buffer, s->vrtsp_state->curr_time); + s->vrtsp_state->cp = pdb_iter_next(&it); } pdb_iter_done(&it); @@ -296,50 +364,60 @@ vidcap_rtsp_grab(void *state, struct audio_frame **audio) { *audio = NULL; - if(pthread_mutex_trylock(&s->lock)==0){ + if(pthread_mutex_trylock(&s->vrtsp_state->lock)==0){ { - s->grab = true; + s->vrtsp_state->grab = true; - while (!s->new_frame) { - s->boss_waiting = true; - pthread_cond_wait(&s->boss_cv, &s->lock); - s->boss_waiting = false; + while (!s->vrtsp_state->new_frame) { + s->vrtsp_state->boss_waiting = true; + pthread_cond_wait(&s->vrtsp_state->boss_cv, &s->vrtsp_state->lock); + s->vrtsp_state->boss_waiting = false; } - gettimeofday(&s->curr_time, NULL); - s->frame->h264_iframe = s->rx_data->iframe; - s->frame->h264_iframe = s->rx_data->iframe; - s->frame->tiles[0].data_len = s->rx_data->buffer_len; - memcpy(s->data + s->nals_size, s->rx_data->frame_buffer, - s->rx_data->buffer_len); - memcpy(s->frame->tiles[0].data, s->data, - s->rx_data->buffer_len + s->nals_size); - s->frame->tiles[0].data_len += s->nals_size; + gettimeofday(&s->vrtsp_state->curr_time, NULL); - if (s->decompress) { - decompress_frame(s->sd, (unsigned char *) s->out_frame, - (unsigned char *) s->frame->tiles[0].data, - s->rx_data->buffer_len + s->nals_size, 0); - s->frame->tiles[0].data = s->out_frame; //TODO memcpy? - s->frame->tiles[0].data_len = vc_get_linesize(s->des.width, UYVY) - * s->des.height; //TODO reconfigurable? + s->vrtsp_state->frame->tiles[0].data_len = s->vrtsp_state->frame->h264_buffer_len; + s->vrtsp_state->frame->tiles[0].data = s->vrtsp_state->frame->h264_buffer; + + if(s->vrtsp_state->frame->h264_offset_len>0 && s->vrtsp_state->frame->h264_frame_type == INTRA){ + memcpy(s->vrtsp_state->frame->tiles[0].data, s->vrtsp_state->frame->h264_offset_buffer, s->vrtsp_state->frame->h264_offset_len); } - s->new_frame = false; - if (s->worker_waiting) { - pthread_cond_signal(&s->worker_cv); + if (s->vrtsp_state->decompress) { + if(s->vrtsp_state->des.width != s->vrtsp_state->frame->h264_width || s->vrtsp_state->des.height != s->vrtsp_state->frame->h264_height){ + s->vrtsp_state->des.width = s->vrtsp_state->frame->h264_width; + s->vrtsp_state->des.height = s->vrtsp_state->frame->h264_height; + decompress_done(s->vrtsp_state->sd); + s->vrtsp_state->frame->color_spec = H264; + if (init_decompressor(s->vrtsp_state) == 0) + return NULL; + s->vrtsp_state->frame->color_spec = UYVY; + } + + decompress_frame(s->vrtsp_state->sd, (unsigned char *) s->vrtsp_state->out_frame, + (unsigned char *) s->vrtsp_state->frame->tiles[0].data, + s->vrtsp_state->frame->h264_buffer_len, 0); + s->vrtsp_state->frame->tiles[0].data = s->vrtsp_state->out_frame; //TODO memcpy? + s->vrtsp_state->frame->tiles[0].data_len = vc_get_linesize(s->vrtsp_state->des.width, UYVY) + * s->vrtsp_state->des.height; //TODO reconfigurable? + } + s->vrtsp_state->new_frame = false; + + if (s->vrtsp_state->worker_waiting) { + pthread_cond_signal(&s->vrtsp_state->worker_cv); } } - pthread_mutex_unlock(&s->lock); - gettimeofday(&s->t, NULL); - double seconds = tv_diff(s->t, s->t0); + pthread_mutex_unlock(&s->vrtsp_state->lock); + + gettimeofday(&s->vrtsp_state->t, NULL); + double seconds = tv_diff(s->vrtsp_state->t, s->vrtsp_state->t0); if (seconds >= 5) { - float fps = s->frames / seconds; + float fps = s->vrtsp_state->frames / seconds; fprintf(stderr, "[rtsp capture] %d frames in %g seconds = %g FPS\n", - s->frames, seconds, fps); - s->t0 = s->t; - s->frames = 0; + s->vrtsp_state->frames, seconds, fps); + s->vrtsp_state->t0 = s->vrtsp_state->t; + s->vrtsp_state->frames = 0; //TODO: Threshold of ¿1fps? in order to update fps parameter. Now a higher fps is fixed to 30fps... //if (fps > s->fps + 1 || fps < s->fps - 1) { // debug_msg( @@ -348,11 +426,11 @@ vidcap_rtsp_grab(void *state, struct audio_frame **audio) { // s->fps = fps; // } } - s->frames++; - s->grab = false; + s->vrtsp_state->frames++; + s->vrtsp_state->grab = false; } - return s->frame; + return s->vrtsp_state->frame; } void * @@ -364,32 +442,45 @@ vidcap_rtsp_init(const struct vidcap_params *params) { if (!s) return NULL; - char *save_ptr = NULL; + s->artsp_state = calloc(1,sizeof(struct audio_rtsp_state)); + s->vrtsp_state = calloc(1,sizeof(struct video_rtsp_state)); - gettimeofday(&s->t0, NULL); - s->frames = 0; - s->nals = malloc(1024); - s->grab = false; + //TODO now static codec assignment, to be dynamic as a function of supported codecs + s->vrtsp_state->codec = ""; + s->artsp_state->codec = ""; + s->artsp_state->control = ""; + s->artsp_state->control = ""; + + int len = -1; + char *save_ptr = NULL; + s->avType = none; //-1 none, 0 a&v, 1 v, 2 a + + gettimeofday(&s->vrtsp_state->t0, NULL); + s->vrtsp_state->frames = 0; + s->vrtsp_state->grab = FALSE; s->addr = "127.0.0.1"; - s->device = NULL; - s->rtcp_bw = 5 * 1024 * 1024; /* FIXME */ - s->ttl = 255; + s->vrtsp_state->device = NULL; + s->vrtsp_state->rtcp_bw = 5 * 1024 * 1024; /* FIXME */ + s->vrtsp_state->ttl = 255; - s->mcast_if = NULL; - s->required_connections = 1; + s->vrtsp_state->mcast_if = NULL; + s->vrtsp_state->required_connections = 1; - s->timeout.tv_sec = 0; - s->timeout.tv_usec = 10000; + s->vrtsp_state->timeout.tv_sec = 0; + s->vrtsp_state->timeout.tv_usec = 10000; - s->device = (struct rtp *) malloc( - (s->required_connections) * sizeof(struct rtp *)); - s->participants = pdb_init(); + s->vrtsp_state->device = (struct rtp *) malloc( + (s->vrtsp_state->required_connections) * sizeof(struct rtp *)); + s->vrtsp_state->participants = pdb_init(); - s->rx_data = malloc(sizeof(struct std_frame_received)); - s->new_frame = false; + s->vrtsp_state->new_frame = FALSE; - s->in_codec = malloc(sizeof(uint32_t *) * 10); + s->vrtsp_state->in_codec = malloc(sizeof(uint32_t *) * 10); + + s->vrtsp_state->frame = vf_alloc(1); + s->vrtsp_state->frame->h264_offset_buffer = malloc(2048); + s->vrtsp_state->frame->h264_offset_len = 0; s->uri = NULL; s->curl = NULL; @@ -426,42 +517,19 @@ vidcap_rtsp_init(const struct vidcap_params *params) { } break; case 1: - if (tmp) { //TODO check if it's a number - s->port = atoi(tmp); - } else { - printf("\n[rtsp] Wrong format for port! \n"); - show_help(); - exit(0); - } - break; - case 2: if (tmp) { //TODO check if it's a number - s->width = atoi(tmp); - } else { - printf("\n[rtsp] Wrong format for width! \n"); - show_help(); - exit(0); - } - break; - case 3: - if (tmp) { //TODO check if it's a number - s->height = atoi(tmp); + s->vrtsp_state->port = atoi(tmp); //Now checking if we have user and password parameters... - if (s->height == 0) { - int ntmp = 0; - ntmp = s->width; - s->width = s->port; - s->height = ntmp; + if (s->vrtsp_state->port == 0) { sprintf(s->uri, "rtsp:%s", uri_tmp1); - s->port = atoi(uri_tmp2); + s->vrtsp_state->port = atoi(uri_tmp2); if (tmp) { if (strcmp(tmp, "true") == 0) - s->decompress = true; + s->vrtsp_state->decompress = TRUE; else if (strcmp(tmp, "false") == 0) - s->decompress = false; + s->vrtsp_state->decompress = FALSE; else { - printf( - "\n[rtsp] Wrong format for boolean decompress flag! \n"); + printf("\n[rtsp] Wrong format for boolean decompress flag! \n"); show_help(); exit(0); } @@ -474,12 +542,12 @@ vidcap_rtsp_init(const struct vidcap_params *params) { exit(0); } break; - case 4: + case 2: if (tmp) { if (strcmp(tmp, "true") == 0) - s->decompress = true; + s->vrtsp_state->decompress = TRUE; else if (strcmp(tmp, "false") == 0) - s->decompress = false; + s->vrtsp_state->decompress = FALSE; else { printf( "\n[rtsp] Wrong format for boolean decompress flag! \n"); @@ -489,7 +557,7 @@ vidcap_rtsp_init(const struct vidcap_params *params) { } else continue; break; - case 5: + case 3: continue; } fmt = NULL; @@ -497,96 +565,98 @@ vidcap_rtsp_init(const struct vidcap_params *params) { } } //re-check parameters - if (s->height == 0) { - int ntmp = 0; - ntmp = s->width; - s->width = (int) s->port; - s->height = (int) ntmp; + if (s->vrtsp_state->port == 0) { sprintf(s->uri, "rtsp:%s", uri_tmp1); - s->port = (int) atoi(uri_tmp2); + s->vrtsp_state->port = (int) atoi(uri_tmp2); } + s->vrtsp_state->frame->h264_width = DEFAULT_VIDEO_FRAME_WIDTH/2; + s->vrtsp_state->frame->h264_height = DEFAULT_VIDEO_FRAME_HEIGHT/2; + debug_msg("[rtsp] selected flags:\n"); debug_msg("\t uri: %s\n",s->uri); - debug_msg("\t port: %d\n", s->port); - debug_msg("\t width: %d\n",s->width); - debug_msg("\t height: %d\n",s->height); - debug_msg("\t decompress: %d\n\n",s->decompress); + debug_msg("\t port: %d\n", s->vrtsp_state->port); + debug_msg("\t decompress: %d\n\n",s->vrtsp_state->decompress); if (uri_tmp1 != NULL) free(uri_tmp1); if (uri_tmp2 != NULL) free(uri_tmp2); - s->rx_data->frame_buffer = malloc(4 * s->width * s->height); - s->data = malloc(4 * s->width * s->height + s->nals_size); + len = init_rtsp(s->uri, s->vrtsp_state->port, s, s->vrtsp_state->frame->h264_offset_buffer); - s->frame = vf_alloc(1); - s->frame->isStd = TRUE; - s->frame->h264_bframe = FALSE; - s->frame->h264_iframe = FALSE; - s->tile = vf_get_tile(s->frame, 0); - vf_get_tile(s->frame, 0)->width = s->width; - vf_get_tile(s->frame, 0)->height = s->height; + if(len < 0){ + return NULL; + }else{ + s->vrtsp_state->frame->h264_offset_len = len; + } + + s->vrtsp_state->frame->h264_buffer = malloc(4 * s->vrtsp_state->frame->h264_width * s->vrtsp_state->frame->h264_height); + + s->vrtsp_state->frame->h264_buffer_len = 0; + s->vrtsp_state->frame->h264_media_time = 0; + s->vrtsp_state->frame->h264_seqno = 0; + + s->vrtsp_state->frame->isStd = TRUE; + s->vrtsp_state->frame->h264_frame_type = BFRAME; + + s->vrtsp_state->tile = vf_get_tile(s->vrtsp_state->frame, 0); + vf_get_tile(s->vrtsp_state->frame, 0)->width = s->vrtsp_state->frame->h264_width; + vf_get_tile(s->vrtsp_state->frame, 0)->height = s->vrtsp_state->frame->h264_height; //TODO fps should be autodetected, now reset and controlled at vidcap_grab function - s->frame->fps = 30; - s->fps = 30; - s->frame->interlacing = PROGRESSIVE; + s->vrtsp_state->frame->fps = 30; + s->vrtsp_state->fps = 30; + s->vrtsp_state->frame->interlacing = PROGRESSIVE; - s->frame->tiles[0].data = calloc(1, s->width * s->height); + s->vrtsp_state->frame->tiles[0].data = calloc(1, s->vrtsp_state->frame->h264_width * s->vrtsp_state->frame->h264_height); - s->should_exit = false; + s->should_exit = FALSE; - s->device = rtp_init_if(NULL, s->mcast_if, s->port, 0, s->ttl, s->rtcp_bw, - 0, rtp_recv_callback, (void *) s->participants, 0, false); + s->vrtsp_state->device = rtp_init_if(NULL, s->vrtsp_state->mcast_if, s->vrtsp_state->port, 0, s->vrtsp_state->ttl, s->vrtsp_state->rtcp_bw, + 0, rtp_recv_callback, (void *) s->vrtsp_state->participants, false, true); - if (s->device != NULL) { - if (!rtp_set_option(s->device, RTP_OPT_WEAK_VALIDATION, 1)) { + if (s->vrtsp_state->device != NULL) { + if (!rtp_set_option(s->vrtsp_state->device, RTP_OPT_WEAK_VALIDATION, 1)) { debug_msg("[rtsp] RTP INIT - set option\n"); return NULL; } - if (!rtp_set_sdes(s->device, rtp_my_ssrc(s->device), - RTCP_SDES_TOOL, PACKAGE_STRING, strlen(PACKAGE_STRING))) { + if (!rtp_set_sdes(s->vrtsp_state->device, rtp_my_ssrc(s->vrtsp_state->device), + RTCP_SDES_TOOL, PACKAGE_STRING, strlen(PACKAGE_STRING))) { debug_msg("[rtsp] RTP INIT - set sdes\n"); return NULL; } - int ret = rtp_set_recv_buf(s->device, INITIAL_VIDEO_RECV_BUFFER_SIZE); + int ret = rtp_set_recv_buf(s->vrtsp_state->device, INITIAL_VIDEO_RECV_BUFFER_SIZE); if (!ret) { debug_msg("[rtsp] RTP INIT - set recv buf \nset command: sudo sysctl -w net.core.rmem_max=9123840\n"); return NULL; } - if (!rtp_set_send_buf(s->device, 1024 * 56)) { + if (!rtp_set_send_buf(s->vrtsp_state->device, 1024 * 56)) { debug_msg("[rtsp] RTP INIT - set send buf\n"); return NULL; } - ret=pdb_add(s->participants, rtp_my_ssrc(s->device)); + ret=pdb_add(s->vrtsp_state->participants, rtp_my_ssrc(s->vrtsp_state->device)); } debug_msg("[rtsp] rtp receiver init done\n"); - pthread_mutex_init(&s->lock, NULL); - pthread_cond_init(&s->boss_cv, NULL); - pthread_cond_init(&s->worker_cv, NULL); + pthread_mutex_init(&s->vrtsp_state->lock, NULL); + pthread_cond_init(&s->vrtsp_state->boss_cv, NULL); + pthread_cond_init(&s->vrtsp_state->worker_cv, NULL); - s->boss_waiting = false; - s->worker_waiting = false; + s->vrtsp_state->boss_waiting = false; + s->vrtsp_state->worker_waiting = false; - s->nals_size = init_rtsp(s->uri, s->port, s, s->nals); - - if (s->nals_size >= 0) - memcpy(s->data, s->nals, s->nals_size); - else - return NULL; - - if (s->decompress) { - if (init_decompressor(s) == 0) + if (s->vrtsp_state->decompress) { + s->vrtsp_state->frame->color_spec = H264; + if (init_decompressor(s->vrtsp_state) == 0) return NULL; - s->frame->color_spec = UYVY; + s->vrtsp_state->frame->color_spec = UYVY; } - pthread_create(&s->rtsp_thread_id, NULL, vidcap_rtsp_thread, s); + pthread_create(&s->vrtsp_state->vrtsp_thread_id, NULL, vidcap_rtsp_thread, s); + pthread_create(&s->keep_alive_rtsp_thread_id, NULL, keep_alive_thread, s); debug_msg("[rtsp] rtsp capture init done\n"); @@ -611,11 +681,18 @@ init_rtsp(char* rtsp_uri, int rtsp_port, void *state, char* nals) { char *sdp_filename = malloc(strlen(url) + 32); char *control = malloc(150 * sizeof(char *)); memset(control, 0, 150 * sizeof(char *)); - char transport[256]; - bzero(transport, 256); + char Atransport[256]; + char Vtransport[256]; + bzero(Atransport, 256); + bzero(Vtransport, 256); int port = rtsp_port; + get_sdp_filename(url, sdp_filename); - sprintf(transport, "RTP/AVP;unicast;client_port=%d-%d", port, port + 1); + + sprintf(Vtransport, "RTP/AVP;unicast;client_port=%d-%d", port, port + 1); + + //THIS AUDIO PORTS ARE AS DEFAULT UG AUDIO PORTS BUT AREN'T RELATED... + sprintf(Atransport, "RTP/AVP;unicast;client_port=%d-%d", port+2, port + 3); /* initialize curl */ res = curl_global_init(CURL_GLOBAL_ALL); @@ -644,28 +721,44 @@ init_rtsp(char* rtsp_uri, int rtsp_port, void *state, char* nals) { //http://curl.haxx.se/libcurl/c/curl_easy_perform.html /* request server options */ - rtsp_options(curl, uri); - debug_msg("sdp_file: %s\n", sdp_filename); - /* request session description and write response to sdp file */ - rtsp_describe(curl, uri, sdp_filename); - debug_msg("sdp_file!!!!: %s\n", sdp_filename); - /* get media control attribute from sdp file */ - get_media_control_attribute(sdp_filename, control); - - /* set incoming media codec attribute from sdp file */ - if (set_codec_attribute_from_incoming_media(sdp_filename, s) == 0) + if(rtsp_options(curl, uri)==0){ return -1; + } - /* setup media stream */ - sprintf(uri, "%s/%s", url, control); - rtsp_setup(curl, uri, transport); + /* request session description and write response to sdp file */ + if(rtsp_describe(curl, uri, sdp_filename)==0){ + return -1; + } - /* start playing media stream */ - sprintf(uri, "%s", url); - rtsp_play(curl, uri, range); + setup_codecs_and_controls_from_sdp(sdp_filename, s); + if (s->vrtsp_state->codec == "H264"){ + s->vrtsp_state->frame->color_spec = H264; + sprintf(uri, "%s/%s", url, s->vrtsp_state->control); + debug_msg("\n V URI = %s\n",uri); + if(rtsp_setup(curl, uri, Vtransport)==0){ + return -1; + } + sprintf(uri, "%s", url); + } + if (s->artsp_state->codec == "PCMU"){ + sprintf(uri, "%s/%s", url, s->artsp_state->control); + debug_msg("\n A URI = %s\n",uri); + if(rtsp_setup(curl, uri, Atransport)==0){ + return -1; + } + sprintf(uri, "%s", url); + } + if (s->artsp_state->codec == "" && s->vrtsp_state->codec == ""){ + return -1; + } + else{ + if(rtsp_play(curl, uri, range)==0){ + return -1; + } + } /* get start nal size attribute from sdp file */ - len_nals = get_nals(sdp_filename, nals); + len_nals = get_nals(sdp_filename, nals, &s->vrtsp_state->frame->h264_width, &s->vrtsp_state->frame->h264_height); s->curl = curl; s->uri = uri; @@ -682,13 +775,116 @@ init_rtsp(char* rtsp_uri, int rtsp_port, void *state, char* nals) { return len_nals; } +void setup_codecs_and_controls_from_sdp(const char *sdp_filename, void *state) { + struct rtsp_state *rtspState; + rtspState = (struct rtsp_state *) state; + + int n=0; + char *line = (char*) malloc(1024); + char* tmpBuff; + int countT = 0; + int countC = 0; + char* codecs[2]; + char* tracks[2]; + for(int q=0; q<2 ; q++){ + codecs[q] = (char*) malloc(10); + tracks[q] = (char*) malloc(10); + } + + FILE* fp; + + fp = fopen(sdp_filename, "r"); + if(fp == 0){ + printf("unable to open asset %s", sdp_filename); + fclose(fp); + return -1; + } + fseek(fp, 0, SEEK_END); + unsigned long fileSize = ftell(fp); + rewind(fp); + + char* buffer = (char*) malloc(fileSize+1); + unsigned long readResult = fread(buffer, sizeof(char), fileSize, fp); + + if(readResult != fileSize){ + printf("something bad happens, read result != file size"); + return -1; + } + buffer[fileSize] = '\0'; + + while (buffer[n] != '\0'){ + getNewLine(buffer,&n,line); + sscanf(line, " a = control: %s", tmpBuff); + tmpBuff = strstr(line, "track"); + if(tmpBuff!=NULL){ + //printf("track = %s\n",tmpBuff); + strncpy(tracks[countT],tmpBuff,strlen(tmpBuff)-2); + tracks[countT][strlen(tmpBuff)-2] = '\0'; + countT++; + } + tmpBuff='\0'; + sscanf(line, " a=rtpmap:96 %s", tmpBuff); + tmpBuff = strstr(line, "H264"); + if(tmpBuff!=NULL){ + //printf("codec = %s\n",tmpBuff); + strncpy(codecs[countC],tmpBuff,4); + codecs[countC][4] = '\0'; + countC++; + } + tmpBuff='\0'; + sscanf(line, " a=rtpmap:97 %s", tmpBuff); + tmpBuff = strstr(line, "PCMU"); + if(tmpBuff!=NULL){ + //printf("codec = %s\n",tmpBuff); + strncpy(codecs[countC],tmpBuff,4); + codecs[countC][4] = '\0'; + countC++; + } + tmpBuff='\0'; + + if(countT > 1 && countC > 1) break; + } + debug_msg("\nTRACK = %s FOR CODEC = %s",tracks[0],codecs[0]); + debug_msg("\nTRACK = %s FOR CODEC = %s\n",tracks[1],codecs[1]); + + for(int p=0;p<2;p++){ + if(strncmp(codecs[p],"H264",4)==0){ + rtspState->vrtsp_state->codec = "H264"; + rtspState->vrtsp_state->control = tracks[p]; + + }if(strncmp(codecs[p],"PCMU",4)==0){ + rtspState->artsp_state->codec = "PCMU"; + rtspState->artsp_state->control = tracks[p]; + } + } + free(line); + free(buffer); + fclose(fp); +} + +void getNewLine(const char* buffer, int* i, char* line){ + int j=0; + while(buffer[*i] != '\n' && buffer[*i] != '\0'){ + j++; + (*i)++; + } + if(buffer[*i] == '\n'){ + j++; + (*i)++; + } + + if(j>0){ + memcpy(line,buffer+(*i)-j,j); + line[j] = '\0'; + } +} /** * Initializes decompressor if required by decompress flag */ static int init_decompressor(void *state) { - struct rtsp_state *sr; - sr = (struct rtsp_state *) state; + struct video_rtsp_state *sr; + sr = (struct video_rtsp_state *) state; sr->sd = (struct state_decompress *) calloc(2, sizeof(struct state_decompress *)); @@ -697,8 +893,8 @@ init_decompressor(void *state) { if (decompress_is_available(LIBAVCODEC_MAGIC)) { sr->sd = decompress_init(LIBAVCODEC_MAGIC); - sr->des.width = sr->width; - sr->des.height = sr->height; + sr->des.width = sr->frame->h264_width; + sr->des.height = sr->frame->h264_height; sr->des.color_spec = sr->frame->color_spec; sr->des.tile_count = 0; sr->des.interlacing = PROGRESSIVE; @@ -707,24 +903,32 @@ init_decompressor(void *state) { vc_get_linesize(sr->des.width, UYVY), UYVY); } else return 0; - sr->out_frame = malloc(sr->width * sr->height * 4); + sr->out_frame = malloc(sr->frame->h264_width * sr->frame->h264_height * 4); return 1; } -static void +/** + * send RTSP GET PARAMS request + */ +static int rtsp_get_parameters(CURL *curl, const char *uri) { CURLcode res = CURLE_OK; - debug_msg("\n[rtsp] GET_PARAMETERS %s\n", uri); my_curl_easy_setopt(curl, CURLOPT_RTSP_STREAM_URI, uri); my_curl_easy_setopt(curl, CURLOPT_RTSP_REQUEST, (long )CURL_RTSPREQ_GET_PARAMETER); - my_curl_easy_perform(curl); + if (curl_easy_perform(curl) != CURLE_OK){ + error_msg("[RTSP GET PARAMETERS] curl_easy_perform failed\n"); + error_msg("[RTSP GET PARAMETERS] could not configure rtsp capture properly, \n\t\tplease check your parameters. \ncleaning...\n\n"); + return 0; + }else{ + return 1; + } } /** * send RTSP OPTIONS request */ -static void +static int rtsp_options(CURL *curl, const char *uri) { char control[1500], *user, *pass, *strtoken; user = malloc(1500); @@ -752,13 +956,20 @@ rtsp_options(CURL *curl, const char *uri) { my_curl_easy_setopt(curl, CURLOPT_PASSWORD, pass); my_curl_easy_setopt(curl, CURLOPT_RTSP_REQUEST, (long )CURL_RTSPREQ_OPTIONS); - my_curl_easy_perform(curl); + + if (curl_easy_perform(curl) != CURLE_OK){ + error_msg("[RTSP OPTIONS] curl_easy_perform failed\n"); + error_msg("[RTSP OPTIONS] could not configure rtsp capture properly, \n\t\tplease check your parameters. \ncleaning...\n\n"); + return 0; + }else{ + return 1; + } } /** * send RTSP DESCRIBE request and write sdp response to a file */ -static void +static int rtsp_describe(CURL *curl, const char *uri, const char *sdp_filename) { CURLcode res = CURLE_OK; FILE *sdp_fp = fopen(sdp_filename, "wt"); @@ -772,17 +983,24 @@ rtsp_describe(CURL *curl, const char *uri, const char *sdp_filename) { my_curl_easy_setopt(curl, CURLOPT_WRITEDATA, sdp_fp); my_curl_easy_setopt(curl, CURLOPT_RTSP_REQUEST, (long )CURL_RTSPREQ_DESCRIBE); - my_curl_easy_perform(curl); + + if (curl_easy_perform(curl) != CURLE_OK){ + error_msg("[RTSP DESCRIBE] curl_easy_perform failed\n"); + error_msg("[RTSP DESCRIBE] could not configure rtsp capture properly, \n\t\tplease check your parameters. \ncleaning...\n\n"); + return 0; + } + my_curl_easy_setopt(curl, CURLOPT_WRITEDATA, stdout); if (sdp_fp != stdout) { fclose(sdp_fp); } + return 1; } /** * send RTSP SETUP request */ -static void +static int rtsp_setup(CURL *curl, const char *uri, const char *transport) { CURLcode res = CURLE_OK; debug_msg("\n[rtsp] SETUP %s\n", uri); @@ -790,34 +1008,54 @@ rtsp_setup(CURL *curl, const char *uri, const char *transport) { my_curl_easy_setopt(curl, CURLOPT_RTSP_STREAM_URI, uri); my_curl_easy_setopt(curl, CURLOPT_RTSP_TRANSPORT, transport); my_curl_easy_setopt(curl, CURLOPT_RTSP_REQUEST, (long )CURL_RTSPREQ_SETUP); - my_curl_easy_perform(curl); + + if (curl_easy_perform(curl) != CURLE_OK){ + error_msg("[RTSP SETUP] curl_easy_perform failed\n"); + error_msg("[RTSP SETUP] could not configure rtsp capture properly, \n\t\tplease check your parameters. \ncleaning...\n\n"); + return 0; + }else{ + return 1; + } } /** * send RTSP PLAY request */ -static void +static int rtsp_play(CURL *curl, const char *uri, const char *range) { CURLcode res = CURLE_OK; debug_msg("\n[rtsp] PLAY %s\n", uri); my_curl_easy_setopt(curl, CURLOPT_RTSP_STREAM_URI, uri); //my_curl_easy_setopt(curl, CURLOPT_RANGE, range); //range not set because we want (right now) no limit range for streaming duration my_curl_easy_setopt(curl, CURLOPT_RTSP_REQUEST, (long )CURL_RTSPREQ_PLAY); - my_curl_easy_perform(curl); + + if (curl_easy_perform(curl) != CURLE_OK){ + error_msg("[RTSP PLAY] curl_easy_perform failed\n"); + error_msg("[RTSP PLAY] could not configure rtsp capture properly, \n\t\tplease check your parameters. \ncleaning...\n\n"); + return 0; + }else{ + return 1; + } } /** * send RTSP TEARDOWN request */ -static void +static int rtsp_teardown(CURL *curl, const char *uri) { CURLcode res = CURLE_OK; debug_msg("\n[rtsp] TEARDOWN %s\n", uri); my_curl_easy_setopt(curl, CURLOPT_RTSP_REQUEST, (long )CURL_RTSPREQ_TEARDOWN); - my_curl_easy_perform(curl); -} + if (curl_easy_perform(curl) != CURLE_OK){ + error_msg("[RTSP TEARD DOWN] curl_easy_perform failed\n"); + error_msg("[RTSP TEARD DOWN] could not configure rtsp capture properly, \n\t\tplease check your parameters. \ncleaning...\n\n"); + return 0; + }else{ + return 1; + } +} /** * convert url into an sdp filename */ @@ -834,86 +1072,6 @@ get_sdp_filename(const char *url, char *sdp_filename) { } } -/** - * scan sdp file for media control attribute - */ -static void -get_media_control_attribute(const char *sdp_filename, char *control) { - int max_len = 1256; - char *s = malloc(max_len); - - char *track = malloc(max_len); - char *track_ant = malloc(max_len); - - FILE *sdp_fp = fopen(sdp_filename, "rt"); - //control[0] = '\0'; - if (sdp_fp != NULL) { - while (fgets(s, max_len - 2, sdp_fp) != NULL) { - sscanf(s, " a = control: %s", track_ant); - if (strcmp(track_ant, "") != 0) { - track = strstr(track_ant, "track"); - if (track != NULL) - break; - } - } - - fclose(sdp_fp); - } - free(s); - memcpy(control, track, strlen(track)); -} - -/** - * scan sdp file for incoming codec and set it - */ -static int -set_codec_attribute_from_incoming_media(const char *sdp_filename, void *state) { - struct rtsp_state *sr; - sr = (struct rtsp_state *) state; - - int max_len = 1256; - char *pt = malloc(4 * sizeof(char *)); - char *codec = malloc(32 * sizeof(char *)); - char *s = malloc(max_len); - FILE *sdp_fp = fopen(sdp_filename, "rt"); - - if (sdp_fp != NULL) { - while (fgets(s, max_len - 2, sdp_fp) != NULL) { - sscanf(s, " m = video 0 RTP/AVP %s", pt); - } - fclose(sdp_fp); - } - free(s); - - s = malloc(max_len); - sdp_fp = fopen(sdp_filename, "rt"); - - if (sdp_fp != NULL) { - while (fgets(s, max_len - 2, sdp_fp) != NULL) { - sscanf(s, " a=rtpmap:96 %s", codec); - } - fclose(sdp_fp); - } - free(s); - - char *save_ptr = NULL; - char *tmp; - tmp = strtok_r(codec, "/", &save_ptr); - if (!tmp) { - fprintf(stderr, "[rtsp] no codec atribute found into sdp file...\n"); - return 0; - } - sprintf((char *) sr->in_codec, "%s", tmp); - - if (memcmp(sr->in_codec, "H264", 4) == 0) - sr->frame->color_spec = H264; - else if (memcmp(sr->in_codec, "VP8", 3) == 0) - sr->frame->color_spec = VP8; - else - sr->frame->color_spec = RGBA; - return 1; -} - struct vidcap_type * vidcap_rtsp_probe(void) { struct vidcap_type *vt; @@ -931,29 +1089,41 @@ void vidcap_rtsp_done(void *state) { struct rtsp_state *s = state; - s->should_exit = true; - pthread_join(s->rtsp_thread_id, NULL); + s->should_exit = TRUE; + pthread_join(s->vrtsp_state->vrtsp_thread_id, NULL); + pthread_join(s->keep_alive_rtsp_thread_id, NULL); + + if(s->vrtsp_state->decompress) + decompress_done(s->vrtsp_state->sd); + + rtp_done(s->vrtsp_state->device); + + if(s->vrtsp_state->frame->h264_buffer!=NULL) free(s->vrtsp_state->frame->h264_buffer); + if(s->vrtsp_state->frame->h264_offset_buffer!=NULL) free(s->vrtsp_state->frame->h264_offset_buffer); + if(s->vrtsp_state->frame!=NULL) free(s->vrtsp_state->frame); + if(s->vrtsp_state!=NULL) free(s->vrtsp_state); + if(s->artsp_state!=NULL) free(s->artsp_state); - free(s->rx_data->frame_buffer); - free(s->data); rtsp_teardown(s->curl, s->uri); curl_easy_cleanup(s->curl); s->curl = NULL; - if (s->decompress) - decompress_done(s->sd); - rtp_done(s->device); - free(s); } /** - * scan sdp file for media control attribute to generate nal starting bytes + * scan sdp file for media control attributes to generate coded frame required params (WxH and offset) */ static int -get_nals(const char *sdp_filename, char *nals) { +get_nals(const char *sdp_filename, char *nals, int *width, int *height) { + + uint8_t nalInfo; + uint8_t type; + uint8_t nri; + int k; + int sizeSPS = 0; int max_len = 1500, len_nals = 0; char *s = malloc(max_len); char *sprop; @@ -967,11 +1137,8 @@ get_nals(const char *sdp_filename, char *nals) { gsize length; //gsize is an unsigned int. char *nal_aux, *nals_aux, *nal; nals_aux = malloc(max_len); - nals[0] = 0x00; - nals[1] = 0x00; - nals[2] = 0x00; - nals[3] = 0x01; - len_nals = 4; + memcpy(nals, start_sequence, sizeof(start_sequence)); + len_nals = sizeof(start_sequence); nal_aux = strstr(sprop, "="); nal_aux++; nal = strtok(nal_aux, ",;"); @@ -980,23 +1147,39 @@ get_nals(const char *sdp_filename, char *nals) { memcpy(nals + len_nals, nals_aux, length); len_nals += length; + nalInfo = (uint8_t) nals[4]; + type = nalInfo & 0x1f; + nri = nalInfo & 0x60; + + if (type == 7){ + width_height_from_SDP(width, height , (nals+4), length); + } + while ((nal = strtok(NULL, ",;")) != NULL) { nals_aux = g_base64_decode(nal, &length); if (length) { //convert base64 to hex - nals[len_nals] = 0x00; - nals[len_nals + 1] = 0x00; - nals[len_nals + 2] = 0x00; - nals[len_nals + 3] = 0x01; - len_nals += 4; + memcpy(nals+len_nals, start_sequence, sizeof(start_sequence)); + len_nals += sizeof(start_sequence); memcpy(nals + len_nals, nals_aux, length); len_nals += length; - } //end if (length) { - } //end while ((nal = strtok(NULL, ",;")) != NULL){ - } //end if (sprop != NULL) { - } //end while (fgets(s, max_len - 2, sdp_fp) != NULL) { + + nalInfo = (uint8_t) nals[len_nals - length]; + type = nalInfo & 0x1f; + nri = nalInfo & 0x60; + + if (type == 7){ + width_height_from_SDP(width, height , (nals+(len_nals - length)), length); + } + //assure start sequence injection between sps, pps and other nals + memcpy(nals+len_nals, start_sequence, sizeof(start_sequence)); + len_nals += sizeof(start_sequence); + } + } + } + } fclose(sdp_fp); - } //end if (sdp_fp != NULL) { + } free(s); return len_nals; diff --git a/src/video_rxtx/h264_rtp.cpp b/src/video_rxtx/h264_rtp.cpp index 1d6ee602e..6491c2dc3 100644 --- a/src/video_rxtx/h264_rtp.cpp +++ b/src/video_rxtx/h264_rtp.cpp @@ -53,7 +53,7 @@ h264_rtp_video_rxtx::h264_rtp_video_rxtx(struct module *parent, struct video_exp const char *requested_compression, const char *requested_encryption, const char *receiver, int rx_port, int tx_port, bool use_ipv6, const char *mcast_if, const char *requested_video_fec, int mtu, - long packet_rate, uint8_t avType) : + long packet_rate, rtps_types_t avType) : rtp_video_rxtx(parent, video_exporter, requested_compression, requested_encryption, receiver, rx_port, tx_port, use_ipv6, mcast_if, requested_video_fec, mtu, packet_rate) diff --git a/src/video_rxtx/h264_rtp.h b/src/video_rxtx/h264_rtp.h index b487aa35d..5f9cee75c 100644 --- a/src/video_rxtx/h264_rtp.h +++ b/src/video_rxtx/h264_rtp.h @@ -52,7 +52,7 @@ public: const char *requested_compression, const char *requested_encryption, const char *receiver, int rx_port, int tx_port, bool use_ipv6, const char *mcast_if, const char *requested_video_fec, int mtu, - long packet_rate, uint8_t avType); + long packet_rate, rtps_types_t avType); virtual ~h264_rtp_video_rxtx(); private: virtual void send_frame(struct video_frame *);