+++ /dev/null
-#! /bin/sh
-# Attempt to guess a canonical system name.
-# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
-# 2011 Free Software Foundation, Inc.
-
-timestamp='2011-05-11'
-
-# 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
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
-# 02110-1301, USA.
-#
-# 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.
-
-
-# Originally written by Per Bothner. Please send patches (context
-# diff format) to <config-patches@gnu.org> and include a 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.
-#
-# 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
-
-me=`echo "$0" | sed -e 's,.*/,,'`
-
-usage="\
-Usage: $0 [OPTION]
-
-Output the configuration name of the system \`$me' is run on.
-
-Operation modes:
- -h, --help print this help, then exit
- -t, --time-stamp print date of last modification, then exit
- -v, --version print version number, then exit
-
-Report bugs and patches to <config-patches@gnu.org>."
-
-version="\
-GNU config.guess ($timestamp)
-
-Originally written by Per Bothner.
-Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 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."
-
-help="
-Try \`$me --help' for more information."
-
-# Parse command line
-while test $# -gt 0 ; do
- case $1 in
- --time-stamp | --time* | -t )
- echo "$timestamp" ; exit ;;
- --version | -v )
- echo "$version" ; exit ;;
- --help | --h* | -h )
- echo "$usage"; exit ;;
- -- ) # Stop option processing
- shift; break ;;
- - ) # Use stdin as input.
- break ;;
- -* )
- echo "$me: invalid option $1$help" >&2
- exit 1 ;;
- * )
- break ;;
- esac
-done
-
-if test $# != 0; then
- echo "$me: too many arguments$help" >&2
- exit 1
-fi
-
-trap '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.
-
-# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
-# use `HOST_CC' if defined, but it is deprecated.
-
-# 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
- if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then
- CC_FOR_BUILD="$c"; break ;
- fi ;
- done ;
- 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 ; 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)
-if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
- PATH=$PATH:/.attbin ; export PATH
-fi
-
-UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
-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
-
-# 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*,
- # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently
- # switched to ELF, *-*-netbsd* would select the old
- # object file format. This provides both forward
- # compatibility and a consistent mechanism for selecting the
- # object file format.
- #
- # Note: NetBSD doesn't particularly care about the vendor
- # portion of the name. We always set it to "unknown".
- sysctl="sysctl -n hw.machine_arch"
- 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
- # to ELF recently, or will in the future.
- case "${UNAME_MACHINE_ARCH}" in
- arm*|i386|m68k|ns32k|sh3*|sparc|vax)
- eval $set_cc_for_build
- if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
- | grep -q __ELF__
- then
- # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
- # Return netbsd for either. FIX?
- os=netbsd
- else
- os=netbsdelf
- fi
- ;;
- *)
- os=netbsd
- ;;
- esac
- # The OS release
- # 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 ;;
- *:OpenBSD:*:*)
- 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:*:*)
- case $UNAME_RELEASE in
- *4.0)
- UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
- ;;
- *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.
- 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 ;;
- 21064:Windows_NT:50:3)
- echo alpha-dec-winnt3.5
- exit ;;
- Amiga*:UNIX_System_V:4.0:*)
- echo m68k-unknown-sysv4
- exit ;;
- *:[Aa]miga[Oo][Ss]:*:*)
- echo ${UNAME_MACHINE}-unknown-amigaos
- exit ;;
- *:[Mm]orph[Oo][Ss]:*:*)
- echo ${UNAME_MACHINE}-unknown-morphos
- exit ;;
- *:OS/390:*:*)
- echo i370-ibm-openedition
- 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 ;;
- arm:riscos:*:*|arm:RISCOS:*:*)
- echo arm-unknown-riscos
- exit ;;
- SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
- echo hppa1.1-hitachi-hiuxmpp
- 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
- echo pyramid-pyramid-sysv3
- else
- echo pyramid-pyramid-bsd
- fi
- exit ;;
- NILE*:*:*:dcosx)
- echo pyramid-pyramid-svr4
- 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 ;;
- sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
- echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
- 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 ;;
- sun4*:SunOS:*:*)
- case "`/usr/bin/arch -k`" in
- Series*|S4*)
- UNAME_RELEASE=`uname -v`
- ;;
- esac
- # Japanese Language versions have a version number like `4.1.3-JL'.
- echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
- exit ;;
- sun3*:SunOS:*:*)
- echo m68k-sun-sunos${UNAME_RELEASE}
- 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
- case "`/bin/arch`" in
- sun3)
- echo m68k-sun-sunos${UNAME_RELEASE}
- ;;
- sun4)
- echo sparc-sun-sunos${UNAME_RELEASE}
- ;;
- esac
- exit ;;
- aushp:SunOS:*:*)
- echo sparc-auspex-sunos${UNAME_RELEASE}
- 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
- # > m68000). The system name ranges from "MiNT" over "FreeMiNT"
- # to the lowercase version "mint" (or "freemint"). Finally
- # the system name "TOS" denotes a system which is actually not
- # 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 ;;
- atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
- echo m68k-atari-mint${UNAME_RELEASE}
- exit ;;
- *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
- echo m68k-atari-mint${UNAME_RELEASE}
- exit ;;
- milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
- echo m68k-milan-mint${UNAME_RELEASE}
- exit ;;
- hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
- echo m68k-hades-mint${UNAME_RELEASE}
- exit ;;
- *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
- 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 ;;
- RISC*:Mach:*:*)
- echo mips-dec-mach_bsd4.3
- exit ;;
- RISC*:ULTRIX:*:*)
- echo mips-dec-ultrix${UNAME_RELEASE}
- exit ;;
- VAX*:ULTRIX*:*:*)
- echo vax-dec-ultrix${UNAME_RELEASE}
- exit ;;
- 2020:CLIX:*:* | 2430:CLIX:*:*)
- echo clipper-intergraph-clix${UNAME_RELEASE}
- exit ;;
- mips:*:*:UMIPS | mips:*:*:RISCos)
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
-#ifdef __cplusplus
-#include <stdio.h> /* for printf() prototype */
- int main (int argc, char *argv[]) {
-#else
- int main (argc, argv) int argc; char *argv[]; {
-#endif
- #if defined (host_mips) && defined (MIPSEB)
- #if defined (SYSTYPE_SYSV)
- printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
- #endif
- #if defined (SYSTYPE_SVR4)
- printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
- #endif
- #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
- printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
- #endif
- #endif
- exit (-1);
- }
-EOF
- $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 ;;
- Motorola:PowerMAX_OS:*:*)
- echo powerpc-motorola-powermax
- 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 ;;
- m88k:CX/UX:7*:*)
- echo m88k-harris-cxux7
- exit ;;
- m88k:*:4*:R4*)
- echo m88k-motorola-sysv4
- exit ;;
- m88k:*:3*:R3*)
- echo m88k-motorola-sysv3
- exit ;;
- AViiON:dgux:*:*)
- # 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 ] || \
- [ ${TARGET_BINARY_INTERFACE}x = x ]
- then
- echo m88k-dg-dgux${UNAME_RELEASE}
- else
- echo m88k-dg-dguxbcs${UNAME_RELEASE}
- fi
- else
- echo i586-dg-dgux${UNAME_RELEASE}
- fi
- exit ;;
- M88*:DolphinOS:*:*) # DolphinOS (SVR3)
- echo m88k-dolphin-sysv3
- exit ;;
- M88*:*:R3*:*)
- # Delta 88k system running SVR3
- echo m88k-motorola-sysv3
- exit ;;
- XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
- echo m88k-tektronix-sysv3
- exit ;;
- Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
- echo m68k-tektronix-bsd
- exit ;;
- *:IRIX*:*:*)
- echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
- 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 ;; # Note that: echo "'`uname -s`'" gives 'AIX '
- i*86:AIX:*:*)
- echo i386-ibm-aix
- exit ;;
- ia64:AIX:*:*)
- if [ -x /usr/bin/oslevel ] ; then
- IBM_REV=`/usr/bin/oslevel`
- else
- IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
- fi
- echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
- exit ;;
- *:AIX:2:3)
- if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
- #include <sys/systemcfg.h>
-
- main()
- {
- if (!__power_pc())
- exit(1);
- puts("powerpc-ibm-aix3.2.5");
- exit(0);
- }
-EOF
- 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 ;;
- *: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
- else
- IBM_ARCH=powerpc
- fi
- if [ -x /usr/bin/oslevel ] ; then
- IBM_REV=`/usr/bin/oslevel`
- else
- IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
- fi
- echo ${IBM_ARCH}-ibm-aix${IBM_REV}
- exit ;;
- *:AIX:*:*)
- echo rs6000-ibm-aix
- exit ;;
- ibmrt:4.4BSD:*|romp-ibm:BSD:*)
- echo romp-ibm-bsd4.4
- exit ;;
- ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and
- echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to
- exit ;; # report: romp-ibm BSD 4.3
- *:BOSX:*:*)
- echo rs6000-bull-bosx
- exit ;;
- DPX/2?00:B.O.S.:*:*)
- echo m68k-bull-sysv3
- exit ;;
- 9000/[34]??:4.3bsd:1.*:*)
- echo m68k-hp-bsd
- exit ;;
- hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
- echo m68k-hp-bsd4.4
- exit ;;
- 9000/[34678]??:HP-UX:*:*)
- HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
- case "${UNAME_MACHINE}" in
- 9000/31? ) HP_ARCH=m68000 ;;
- 9000/[34]?? ) HP_ARCH=m68k ;;
- 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" ;;
- '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20
- esac ;;
- esac
- fi
- if [ "${HP_ARCH}" = "" ]; then
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
-
- #define _HPUX_SOURCE
- #include <stdlib.h>
- #include <unistd.h>
-
- 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);
- }
-EOF
- (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 ;;
- ia64:HP-UX:*:*)
- HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
- echo ia64-hp-hpux${HPUX_REV}
- exit ;;
- 3050*:HI-UX:*:*)
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
- #include <unistd.h>
- int
- main ()
- {
- long cpu = sysconf (_SC_CPU_VERSION);
- /* The order matters, because CPU_IS_HP_MC68K erroneously returns
- true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct
- results, however. */
- if (CPU_IS_PA_RISC (cpu))
- {
- switch (cpu)
- {
- case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
- case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
- case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
- default: puts ("hppa-hitachi-hiuxwe2"); break;
- }
- }
- else if (CPU_IS_HP_MC68K (cpu))
- puts ("m68k-hitachi-hiuxwe2");
- else puts ("unknown-hitachi-hiuxwe2");
- exit (0);
- }
-EOF
- $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` &&
- { echo "$SYSTEM_NAME"; exit; }
- echo unknown-hitachi-hiuxwe2
- exit ;;
- 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
- echo hppa1.1-hp-bsd
- exit ;;
- 9000/8??:4.3bsd:*:*)
- echo hppa1.0-hp-bsd
- exit ;;
- *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
- echo hppa1.0-hp-mpeix
- exit ;;
- hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
- echo hppa1.1-hp-osf
- exit ;;
- hp8??:OSF1:*:*)
- echo hppa1.0-hp-osf
- exit ;;
- i*86:OSF1:*:*)
- if [ -x /usr/sbin/sysversion ] ; then
- echo ${UNAME_MACHINE}-unknown-osf1mk
- else
- echo ${UNAME_MACHINE}-unknown-osf1
- fi
- exit ;;
- parisc*:Lites*:*:*)
- echo hppa1.1-hp-lites
- exit ;;
- C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
- echo c1-convex-bsd
- exit ;;
- C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
- if getsysinfo -f scalar_acc
- then echo c32-convex-bsd
- else echo c2-convex-bsd
- fi
- exit ;;
- C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
- echo c34-convex-bsd
- exit ;;
- C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
- echo c38-convex-bsd
- exit ;;
- C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
- echo c4-convex-bsd
- exit ;;
- CRAY*Y-MP:*:*:*)
- echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
- 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 ;;
- CRAY*TS:*:*:*)
- echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
- exit ;;
- CRAY*T3E:*:*:*)
- echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
- exit ;;
- CRAY*SV1:*:*:*)
- echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
- 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 ;;
- 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 ;;
- sparc*:BSD/OS:*:*)
- echo sparc-unknown-bsdi${UNAME_RELEASE}
- exit ;;
- *:BSD/OS:*:*)
- echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
- exit ;;
- *:FreeBSD:*:*)
- case ${UNAME_MACHINE} in
- pc98)
- echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
- amd64)
- echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
- *)
- echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
- esac
- exit ;;
- i*:CYGWIN*:*)
- echo ${UNAME_MACHINE}-pc-cygwin
- exit ;;
- *:MINGW*:*)
- echo ${UNAME_MACHINE}-pc-mingw32
- exit ;;
- i*:windows32*:*)
- # uname -m includes "-pc" on this system.
- echo ${UNAME_MACHINE}-mingw32
- exit ;;
- i*:PW*:*)
- echo ${UNAME_MACHINE}-pc-pw32
- 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 i586-pc-interix
- exit ;;
- i*:UWIN*:*)
- echo ${UNAME_MACHINE}-pc-uwin
- exit ;;
- amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*)
- echo x86_64-unknown-cygwin
- exit ;;
- p*:CYGWIN*:*)
- echo powerpcle-unknown-cygwin
- exit ;;
- prep*:SunOS:5.*:*)
- echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
- exit ;;
- *:GNU:*:*)
- # the GNU system
- echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`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/[-(].*//'`-gnu
- exit ;;
- i*86:Minix:*:*)
- echo ${UNAME_MACHINE}-pc-minix
- exit ;;
- alpha:Linux:*:*)
- case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
- EV5) UNAME_MACHINE=alphaev5 ;;
- EV56) UNAME_MACHINE=alphaev56 ;;
- PCA56) UNAME_MACHINE=alphapca56 ;;
- PCA57) UNAME_MACHINE=alphapca56 ;;
- EV6) UNAME_MACHINE=alphaev6 ;;
- EV67) UNAME_MACHINE=alphaev67 ;;
- EV68*) UNAME_MACHINE=alphaev68 ;;
- esac
- objdump --private-headers /bin/sh | grep -q ld.so.1
- if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
- echo ${UNAME_MACHINE}-unknown-linux-gnu${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-gnu
- else
- if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
- | grep -q __ARM_PCS_VFP
- then
- echo ${UNAME_MACHINE}-unknown-linux-gnueabi
- else
- echo ${UNAME_MACHINE}-unknown-linux-gnueabihf
- fi
- fi
- exit ;;
- avr32*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit ;;
- cris:Linux:*:*)
- echo cris-axis-linux-gnu
- exit ;;
- crisv32:Linux:*:*)
- echo crisv32-axis-linux-gnu
- exit ;;
- frv:Linux:*:*)
- echo frv-unknown-linux-gnu
- exit ;;
- i*86:Linux:*:*)
- LIBC=gnu
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
- #ifdef __dietlibc__
- LIBC=dietlibc
- #endif
-EOF
- eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'`
- echo "${UNAME_MACHINE}-pc-linux-${LIBC}"
- exit ;;
- ia64:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit ;;
- m32r*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit ;;
- m68*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit ;;
- mips:Linux:*:* | mips64:Linux:*:*)
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
- #undef CPU
- #undef ${UNAME_MACHINE}
- #undef ${UNAME_MACHINE}el
- #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
- CPU=${UNAME_MACHINE}el
- #else
- #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
- CPU=${UNAME_MACHINE}
- #else
- CPU=
- #endif
- #endif
-EOF
- eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'`
- test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
- ;;
- or32:Linux:*:*)
- echo or32-unknown-linux-gnu
- exit ;;
- padre:Linux:*:*)
- echo sparc-unknown-linux-gnu
- exit ;;
- parisc64:Linux:*:* | hppa64:Linux:*:*)
- echo hppa64-unknown-linux-gnu
- 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-gnu ;;
- PA8*) echo hppa2.0-unknown-linux-gnu ;;
- *) echo hppa-unknown-linux-gnu ;;
- esac
- exit ;;
- ppc64:Linux:*:*)
- echo powerpc64-unknown-linux-gnu
- exit ;;
- ppc:Linux:*:*)
- echo powerpc-unknown-linux-gnu
- exit ;;
- s390:Linux:*:* | s390x:Linux:*:*)
- echo ${UNAME_MACHINE}-ibm-linux
- exit ;;
- sh64*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit ;;
- sh*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit ;;
- sparc:Linux:*:* | sparc64:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit ;;
- tile*:Linux:*:*)
- echo ${UNAME_MACHINE}-tilera-linux-gnu
- exit ;;
- vax:Linux:*:*)
- echo ${UNAME_MACHINE}-dec-linux-gnu
- exit ;;
- x86_64:Linux:*:*)
- echo x86_64-unknown-linux-gnu
- exit ;;
- xtensa*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- 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 ;;
- 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,
- # I just have to hope. -- rms.
- # Use sysv4.2uw... so that sysv4* matches it.
- echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
- 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
- echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
- else
- echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
- fi
- 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 ;;
- i*86:*:3.2:*)
- if test -f /usr/options/cb.name; then
- UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
- echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
- elif /bin/uname -X 2>/dev/null >/dev/null ; then
- 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|grep '^Machine.*Pent *II' >/dev/null) \
- && UNAME_MACHINE=i686
- (/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 ;;
- 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 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 ;;
- paragon:*:*:*)
- echo i860-intel-osf1
- 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 ;;
- mini*:CTIX:SYS*5:*)
- # "miniframe"
- echo m68010-convergent-sysv
- 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; }
- /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
- && { 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; } ;;
- 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 ;;
- mc68030:UNIX_System_V:4.*:*)
- echo m68k-atari-sysv4
- exit ;;
- TSUNAMI:LynxOS:2.*:*)
- echo sparc-unknown-lynxos${UNAME_RELEASE}
- exit ;;
- rs6000:LynxOS:2.*:*)
- echo rs6000-unknown-lynxos${UNAME_RELEASE}
- exit ;;
- PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*)
- echo powerpc-unknown-lynxos${UNAME_RELEASE}
- exit ;;
- SM[BE]S:UNIX_SV:*:*)
- echo mips-dde-sysv${UNAME_RELEASE}
- exit ;;
- RM*:ReliantUNIX-*:*:*)
- echo mips-sni-sysv4
- exit ;;
- RM*:SINIX-*:*:*)
- echo mips-sni-sysv4
- exit ;;
- *:SINIX-*:*:*)
- if uname -p 2>/dev/null >/dev/null ; then
- UNAME_MACHINE=`(uname -p) 2>/dev/null`
- echo ${UNAME_MACHINE}-sni-sysv4
- else
- echo ns32k-sni-sysv
- fi
- exit ;;
- PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
- # says <Richard.M.Bartel@ccMail.Census.GOV>
- echo i586-unisys-sysv4
- exit ;;
- *:UNIX_System_V:4*:FTX*)
- # From Gerald Hewes <hewes@openmarket.com>.
- # How about differentiating between stratus architectures? -djm
- echo hppa1.1-stratus-sysv4
- exit ;;
- *:*:*:FTX*)
- # From seanf@swdc.stratus.com.
- echo i860-stratus-sysv4
- 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 ;;
- mc68*:A/UX:*:*)
- echo m68k-apple-aux${UNAME_RELEASE}
- exit ;;
- news*:NEWS-OS:6*:*)
- echo mips-sony-newsos6
- exit ;;
- R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
- if [ -d /usr/nec ]; then
- echo mips-nec-sysv${UNAME_RELEASE}
- else
- echo mips-unknown-sysv${UNAME_RELEASE}
- fi
- exit ;;
- BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only.
- echo powerpc-be-beos
- exit ;;
- BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only.
- echo powerpc-apple-beos
- exit ;;
- BePC:BeOS:*:*) # BeOS running on Intel PC compatible.
- echo i586-pc-beos
- exit ;;
- BePC:Haiku:*:*) # Haiku running on Intel PC compatible.
- echo i586-pc-haiku
- exit ;;
- SX-4:SUPER-UX:*:*)
- echo sx4-nec-superux${UNAME_RELEASE}
- exit ;;
- SX-5:SUPER-UX:*:*)
- echo sx5-nec-superux${UNAME_RELEASE}
- 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 ;;
- *:Rhapsody:*:*)
- echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
- exit ;;
- *:Darwin:*:*)
- UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
- case $UNAME_PROCESSOR in
- i386)
- eval $set_cc_for_build
- 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
- UNAME_PROCESSOR="x86_64"
- fi
- fi ;;
- unknown) UNAME_PROCESSOR=powerpc ;;
- esac
- echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
- exit ;;
- *:procnto*:*:* | *:QNX:[0123456789]*:*)
- UNAME_PROCESSOR=`uname -p`
- if test "$UNAME_PROCESSOR" = "x86"; then
- UNAME_PROCESSOR=i386
- UNAME_MACHINE=pc
- fi
- echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
- exit ;;
- *:QNX:*:4*)
- echo i386-pc-qnx
- 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 ;;
- *:NonStop-UX:*:*)
- echo mips-compaq-nonstopux
- exit ;;
- BS2000:POSIX*:*:*)
- echo bs2000-siemens-sysv
- exit ;;
- DS/*:UNIX_System_V:*:*)
- echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
- exit ;;
- *:Plan9:*:*)
- # "uname -m" is not consistent, so use $cputype instead. 386
- # is converted to i386 for consistency with other x86
- # operating systems.
- if test "$cputype" = "386"; then
- UNAME_MACHINE=i386
- else
- UNAME_MACHINE="$cputype"
- fi
- echo ${UNAME_MACHINE}-unknown-plan9
- exit ;;
- *:TOPS-10:*:*)
- echo pdp10-unknown-tops10
- exit ;;
- *:TENEX:*:*)
- echo pdp10-unknown-tenex
- exit ;;
- KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
- echo pdp10-dec-tops20
- exit ;;
- XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
- echo pdp10-xkl-tops20
- exit ;;
- *:TOPS-20:*:*)
- echo pdp10-unknown-tops20
- exit ;;
- *:ITS:*:*)
- echo pdp10-unknown-its
- 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 ;;
-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 <<EOF
-#ifdef _SEQUENT_
-# include <sys/types.h>
-# include <sys/utsname.h>
-#endif
-main ()
-{
-#if defined (sony)
-#if defined (MIPSEB)
- /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed,
- I don't know.... */
- printf ("mips-sony-bsd\n"); exit (0);
-#else
-#include <sys/param.h>
- printf ("m68k-sony-newsos%s\n",
-#ifdef NEWSOS4
- "4"
-#else
- ""
-#endif
- ); exit (0);
-#endif
-#endif
-
-#if defined (__arm) && defined (__acorn) && defined (__unix)
- printf ("arm-acorn-riscix\n"); exit (0);
-#endif
-
-#if defined (hp300) && !defined (hpux)
- printf ("m68k-hp-bsd\n"); exit (0);
-#endif
-
-#if defined (NeXT)
-#if !defined (__ARCHITECTURE__)
-#define __ARCHITECTURE__ "m68k"
-#endif
- int version;
- version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
- if (version < 4)
- printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
- else
- printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
- exit (0);
-#endif
-
-#if defined (MULTIMAX) || defined (n16)
-#if defined (UMAXV)
- printf ("ns32k-encore-sysv\n"); exit (0);
-#else
-#if defined (CMU)
- printf ("ns32k-encore-mach\n"); exit (0);
-#else
- printf ("ns32k-encore-bsd\n"); exit (0);
-#endif
-#endif
-#endif
-
-#if defined (__386BSD__)
- printf ("i386-pc-bsd\n"); exit (0);
-#endif
-
-#if defined (sequent)
-#if defined (i386)
- printf ("i386-sequent-dynix\n"); exit (0);
-#endif
-#if defined (ns32000)
- printf ("ns32k-sequent-dynix\n"); exit (0);
-#endif
-#endif
-
-#if defined (_SEQUENT_)
- struct utsname un;
-
- uname(&un);
-
- if (strncmp(un.version, "V2", 2) == 0) {
- printf ("i386-sequent-ptx2\n"); exit (0);
- }
- if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
- printf ("i386-sequent-ptx1\n"); exit (0);
- }
- printf ("i386-sequent-ptx\n"); exit (0);
-
-#endif
-
-#if defined (vax)
-# if !defined (ultrix)
-# include <sys/param.h>
-# if defined (BSD)
-# if BSD == 43
- printf ("vax-dec-bsd4.3\n"); exit (0);
-# else
-# if BSD == 199006
- printf ("vax-dec-bsd4.3reno\n"); exit (0);
-# else
- printf ("vax-dec-bsd\n"); exit (0);
-# endif
-# endif
-# else
- printf ("vax-dec-bsd\n"); exit (0);
-# endif
-# else
- printf ("vax-dec-ultrix\n"); exit (0);
-# endif
-#endif
-
-#if defined (alliant) && defined (i860)
- printf ("i860-alliant-bsd\n"); exit (0);
-#endif
-
- exit (1);
-}
-EOF
-
-$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; }
-
-# Convex versions that predate uname can use getsysinfo(1)
-
-if [ -x /usr/convex/getsysinfo ]
-then
- case `getsysinfo -f cpu_type` in
- c1*)
- echo c1-convex-bsd
- exit ;;
- c2*)
- if getsysinfo -f scalar_acc
- then echo c32-convex-bsd
- else echo c2-convex-bsd
- fi
- exit ;;
- c34*)
- echo c34-convex-bsd
- exit ;;
- c38*)
- echo c38-convex-bsd
- exit ;;
- c4*)
- echo c4-convex-bsd
- exit ;;
- esac
-fi
-
-cat >&2 <<EOF
-$0: unable to guess system type
-
-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
-
- 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
-pertinent to <config-patches@gnu.org> in order to provide the needed
-information to handle your system.
-
-config.guess timestamp = $timestamp
-
-uname -m = `(uname -m) 2>/dev/null || echo unknown`
-uname -r = `(uname -r) 2>/dev/null || echo unknown`
-uname -s = `(uname -s) 2>/dev/null || echo unknown`
-uname -v = `(uname -v) 2>/dev/null || echo unknown`
-
-/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
-/bin/uname -X = `(/bin/uname -X) 2>/dev/null`
-
-hostinfo = `(hostinfo) 2>/dev/null`
-/bin/universe = `(/bin/universe) 2>/dev/null`
-/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null`
-/bin/arch = `(/bin/arch) 2>/dev/null`
-/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null`
-/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
-
-UNAME_MACHINE = ${UNAME_MACHINE}
-UNAME_RELEASE = ${UNAME_RELEASE}
-UNAME_SYSTEM = ${UNAME_SYSTEM}
-UNAME_VERSION = ${UNAME_VERSION}
-EOF
-
-exit 1
-
-# Local variables:
-# eval: (add-hook 'write-file-hooks 'time-stamp)
-# time-stamp-start: "timestamp='"
-# time-stamp-format: "%:y-%02m-%02d"
-# time-stamp-end: "'"
-# End:
+++ /dev/null
-\r
-\r
-#ifdef HAVE_CONFIG_H\r
-#include "config.h"\r
-#endif\r
-\r
-#include "piffdemux.h"\r
-#include <glib/gprintf.h>\r
-#include <gst/tag/tag.h>\r
-#include <stdio.h>\r
-#include <stdlib.h>\r
-#include <string.h>\r
-#include <piffatomparser.h>\r
-#include <piffdemux_fourcc.h>\r
-#include <piffpalette.h>\r
-#include <piffdemux_types.h>\r
-#include <piffdemux_dump.h>\r
-\r
-#define PIFF_DEFAULT_TRACKID -1\r
-#define PIFF_DEFAULT_FOURCC 0\r
-#define PIFF_DEFAULT_TIMESCALE 10000000\r
-#define PIFF_DEFAULT_DURATION -1\r
-#define PIFF_DEFAULT_START_TS 0\r
-#define PIFF_DEFAULT_START_TS 0\r
-\r
-#define PIFF_DEFAULT_WIDTH 16\r
-#define PIFF_DEFAULT_HEIGHT 16\r
-#define PIFF_DEFAULT_BPS 16\r
-\r
-#undef DEC_OUT_FRAME_DUMP\r
-\r
-#ifdef DEC_OUT_FRAME_DUMP\r
-#include <stdio.h>\r
-FILE *piffdump = NULL;\r
-#endif\r
-\r
-#define PIFFDEMUX_RB16(x) ((((const unsigned char*)(x))[0] << 8) | ((const unsigned char*)(x))[1])\r
-/* max. size considered 'sane' for non-mdat atoms */\r
-#define PIFFDEMUX_MAX_ATOM_SIZE (25*1024*1024)\r
-\r
-/* if the sample index is larger than this, something is likely wrong */\r
-#define PIFFDEMUX_MAX_SAMPLE_INDEX_SIZE (50*1024*1024)\r
-\r
-GST_DEBUG_CATEGORY (piffdemux_debug);\r
-\r
-typedef struct _PiffDemuxSegment PiffDemuxSegment;\r
-typedef struct _PiffDemuxSample PiffDemuxSample;\r
-typedef struct _PiffDemuxSubSampleEncryption PiffDemuxSubSampleEncryption;\r
-typedef struct _PiffDemuxSubSampleEntryInfo PiffDemuxSubSampleEntryInfo;\r
-\r
-enum\r
-{\r
- PROR_PIFF_0,\r
- PROP_PIFF_MEDIA_CAPS,\r
- PROP_PIFF_MEDIA_TIMESCALE,\r
- PROP_PIFF_MEDIA_DURATION,\r
- PROP_PIFF_MEDIA_START_TIMESTAMP,\r
- PROP_PIFF_IS_LIVE,\r
- PROP_PIFF_LOOKAHEAD_COUNT,\r
- PROP_PIFF_AVG_FRAME_DUR,\r
-};\r
-\r
-enum\r
-{\r
- SIGNAL_LIVE_PARAM,\r
- LAST_SIGNAL\r
-};\r
-\r
-static guint gst_piffdemux_signals[LAST_SIGNAL] = { 0 };\r
-\r
-struct _PiffDemuxSubSampleEntryInfo\r
-{\r
- guint16 LenofClearData;\r
- guint32 LenofEncryptData;\r
-};\r
-\r
-struct _PiffDemuxSubSampleEncryption\r
-{\r
- guint16 n_entries;\r
- PiffDemuxSubSampleEntryInfo *sub_entry;\r
-};\r
-\r
-struct _PiffDemuxSample\r
-{\r
- guint32 size;\r
- gint32 pts_offset; /* Add this value to timestamp to get the pts */\r
- guint64 offset;\r
- guint64 timestamp; /* DTS In mov time */\r
- guint32 duration; /* In mov time */\r
- gboolean keyframe; /* TRUE when this packet is a keyframe */\r
- guint8 *iv; /* initialization vector for decryption*/\r
- PiffDemuxSubSampleEncryption *sub_encry;\r
-};\r
-\r
-/* timestamp is the DTS */\r
-#define PIFFSAMPLE_DTS(stream,sample) gst_util_uint64_scale ((sample)->timestamp,\\r
- GST_SECOND, (stream)->timescale)\r
-/* timestamp + offset is the PTS */\r
-#define PIFFSAMPLE_PTS(stream,sample) gst_util_uint64_scale ((sample)->timestamp + \\r
- (sample)->pts_offset, GST_SECOND, (stream)->timescale)\r
-/* timestamp + duration - dts is the duration */\r
-#define PIFFSAMPLE_DUR_DTS(stream,sample,dts) (gst_util_uint64_scale ((sample)->timestamp + \\r
- (sample)->duration, GST_SECOND, (stream)->timescale) - (dts));\r
-/* timestamp + offset + duration - pts is the duration */\r
-#define PIFFSAMPLE_DUR_PTS(stream,sample,pts) (gst_util_uint64_scale ((sample)->timestamp + \\r
- (sample)->pts_offset + (sample)->duration, GST_SECOND, (stream)->timescale) - (pts));\r
-\r
-#define PIFFSAMPLE_KEYFRAME(stream,sample) ((sample)->keyframe);\r
-\r
-typedef char uuid_t[16];\r
-\r
-static const uuid_t tfxd_uuid = { 0x6d, 0x1d, 0x9b, 0x05,\r
- 0x42, 0xd5, 0x44, 0xe6,\r
- 0x80, 0xe2, 0x14, 0x1d,\r
- 0xaf, 0xf7, 0x57, 0xb2 };\r
-\r
-static const uuid_t tfrf_uuid = { 0xd4, 0x80, 0x7e, 0xf2,\r
- 0xca, 0x39, 0x46, 0x95,\r
- 0x8e, 0x54, 0x26, 0xcb,\r
- 0x9e, 0x46, 0xa7, 0x9f };\r
-\r
-static const uuid_t encrypt_uuid = { 0xa2, 0x39, 0x4f, 0x52,\r
- 0x5a, 0x9b, 0x4f, 0x14,\r
- 0xa2, 0x44, 0x6c, 0x42,\r
- 0x7c, 0x64, 0x8d, 0xf4 };\r
-\r
-#define SE_OVERRIDE_TE_FLAGS 0x000001\r
-#define SE_USE_SUBSAMPLE_ENCRYPTION 0x000002\r
-\r
-typedef enum\r
-{\r
- UUID_UNKNOWN = -1,\r
- UUID_TFXD,\r
- UUID_TFRF,\r
- UUID_SAMPLE_ENCRYPT,\r
-}uuid_type_t;\r
-\r
-struct _PiffDemuxSegment\r
-{\r
- /* global time and duration, all gst time */\r
- guint64 time;\r
- guint64 stop_time;\r
- guint64 duration;\r
- /* media time of trak, all gst time */\r
- guint64 media_start;\r
- guint64 media_stop;\r
- gdouble rate;\r
-};\r
-\r
-\r
-struct _PiffDemuxStream\r
-{\r
- /* stream type */\r
- guint32 subtype;\r
- GstCaps *caps;\r
- guint32 fourcc;\r
-\r
- /* duration/scale */\r
- guint64 duration; /* in timescale */\r
- guint32 timescale;\r
-\r
- /* our samples */\r
- guint32 n_samples;\r
- PiffDemuxSample *samples;\r
- guint32 min_duration; /* duration in timescale of first sample, used for figuring out\r
- the framerate, in timescale units */\r
-\r
- /* if we use chunks or samples */\r
- gboolean sampled;\r
- guint padding;\r
-\r
- /* when a discontinuity is pending */\r
- gboolean discont;\r
-\r
- /* list of buffers to push first */\r
- GSList *buffers;\r
-\r
- /* buffer needs some custom processing, e.g. subtitles */\r
- gboolean need_process;\r
-\r
- /* current position */\r
- guint32 segment_index;\r
- guint32 sample_index;\r
- guint64 time_position; /* in gst time */\r
-\r
- /* the Gst segment we are processing out, used for clipping */\r
- GstSegment segment;\r
-\r
- /* last GstFlowReturn */\r
- GstFlowReturn last_ret;\r
-\r
-\r
- /* quicktime segments */\r
- guint32 n_segments;\r
- PiffDemuxSegment *segments;\r
- guint32 from_sample;\r
- guint32 to_sample;\r
-\r
- gboolean sent_eos;\r
- GstTagList *pending_tags;\r
- gboolean send_global_tags;\r
-\r
- GstEvent *pending_event;\r
-\r
- gboolean sent_nsevent;\r
-\r
- guint64 start_ts;\r
-\r
- guint64 avg_dur; /* average frame duration */\r
-};\r
-\r
-\r
-enum PiffDemuxState\r
-{\r
- PIFFDEMUX_STATE_INITIAL, /* Initial state (haven't got the header yet) */\r
- PIFFDEMUX_STATE_HEADER, /* Parsing the header */\r
- PIFFDEMUX_STATE_MOVIE, /* Parsing/Playing the media data */\r
- PIFFDEMUX_STATE_BUFFER_MDAT /* Buffering the mdat atom */\r
-};\r
-\r
-\r
-static GNode *piffdemux_tree_get_child_by_type (GNode * node, guint32 fourcc);\r
-static GNode *piffdemux_tree_get_child_by_type_full (GNode * node,\r
- guint32 fourcc, GstByteReader * parser);\r
-static GNode *piffdemux_tree_get_sibling_by_type (GNode * node, guint32 fourcc);\r
-static GNode *piffdemux_tree_get_sibling_by_type_full (GNode * node,\r
- guint32 fourcc, GstByteReader * parser);\r
-\r
-static GstStaticPadTemplate gst_piffdemux_sink_template =\r
- GST_STATIC_PAD_TEMPLATE ("sink",\r
- GST_PAD_SINK,\r
- GST_PAD_ALWAYS,\r
- GST_STATIC_CAPS ("application/x-piff")\r
- );\r
-\r
-static GstStaticPadTemplate gst_piffdemux_src_template =\r
-GST_STATIC_PAD_TEMPLATE ("src",\r
- GST_PAD_SRC,\r
- GST_PAD_ALWAYS,\r
- GST_STATIC_CAPS_ANY);\r
-\r
-\r
-GST_BOILERPLATE (GstPiffDemux, gst_piffdemux, GstPiffDemux, GST_TYPE_ELEMENT);\r
-\r
-static void gst_piffdemux_dispose (GObject * object);\r
-\r
-static GstStateChangeReturn gst_piffdemux_change_state (GstElement * element,\r
- GstStateChange transition);\r
-static void\r
-gst_piffdemux_set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);\r
-static void\r
-gst_piffdemux_get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec);\r
-static GstFlowReturn gst_piffdemux_chain (GstPad * sinkpad, GstBuffer * inbuf);\r
-static gboolean gst_piffdemux_handle_sink_event (GstPad * pad, GstEvent * event);\r
-static gboolean piffdemux_parse_node (GstPiffDemux * piffdemux, GNode * node, const guint8 * buffer, guint length);\r
-static gboolean piffdemux_parse_sample_encryption(GstPiffDemux * piffdemux, GstByteReader *sample_encrypt, PiffDemuxStream * stream);\r
-static gboolean piffdemux_parse_mfhd (GstPiffDemux * piffdemux, GstByteReader * mfhd);\r
-static gboolean gst_piffdemux_handle_src_event (GstPad * pad, GstEvent * event);\r
-static const GstQueryType *gst_piffdemux_get_src_query_types (GstPad * pad);\r
-static gboolean gst_piffdemux_handle_src_query (GstPad * pad, GstQuery * query);\r
-\r
-\r
-static gboolean\r
-ConvertH264_MetaDCI_to_3GPPDCI(unsigned char *dci_meta_buf, unsigned int dci_meta_size, unsigned char **dci_3gpp_buf, unsigned int *dci_3gpp_size);\r
-void\r
-__gst_piffdemux_marshal_BOOLEAN__OBJECT (GClosure *closure,\r
- GValue *return_value G_GNUC_UNUSED,\r
- guint n_param_values,\r
- const GValue *param_values,\r
- gpointer invocation_hint G_GNUC_UNUSED,\r
- gpointer marshal_data);\r
-\r
-static void\r
-gst_piffdemux_base_init (gpointer klass)\r
-{\r
- GstElementClass *element_class = GST_ELEMENT_CLASS (klass);\r
-\r
- gst_element_class_add_pad_template (element_class,\r
- gst_static_pad_template_get (&gst_piffdemux_sink_template));\r
- gst_element_class_add_pad_template (element_class,\r
- gst_static_pad_template_get (&gst_piffdemux_src_template));\r
- gst_element_class_set_details_simple (element_class, "PIFF demuxer",\r
- "Codec/Parser",\r
- "Parser for PIFF file format",\r
- "naveen ch <naveen.ch@samsung.com>");\r
-\r
- GST_DEBUG_CATEGORY_INIT (piffdemux_debug, "piffdemux", 0, "piffdemux plugin");\r
-}\r
-\r
-static void\r
-gst_piffdemux_class_init (GstPiffDemuxClass * klass)\r
-{\r
- GObjectClass *gobject_class;\r
- GstElementClass *gstelement_class;\r
-\r
- gobject_class = (GObjectClass *) klass;\r
- gstelement_class = (GstElementClass *) klass;\r
-\r
- parent_class = g_type_class_peek_parent (klass);\r
-\r
- gobject_class->dispose = gst_piffdemux_dispose;\r
- gobject_class->set_property = gst_piffdemux_set_property;\r
- gobject_class->get_property = gst_piffdemux_get_property;\r
-\r
- gstelement_class->change_state = GST_DEBUG_FUNCPTR (gst_piffdemux_change_state);\r
-\r
- g_object_class_install_property (gobject_class, PROP_PIFF_MEDIA_CAPS,\r
- g_param_spec_boxed ("caps", "Caps",\r
- "The allowed caps for the src pad", GST_TYPE_CAPS,\r
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));\r
- \r
- /* timescale of media to be set by application */\r
- g_object_class_install_property (gobject_class, PROP_PIFF_MEDIA_TIMESCALE,\r
- g_param_spec_uint64 ("timescale", "media timescale",\r
- "media timescale in PIFF Manifest", 0, G_MAXUINT64,\r
- PIFF_DEFAULT_TIMESCALE,\r
- G_PARAM_READWRITE));\r
-\r
- g_object_class_install_property (gobject_class, PROP_PIFF_MEDIA_DURATION,\r
- g_param_spec_int64 ("duration", "Duration of media",\r
- "Total duration of the content", -1, G_MAXINT64,\r
- PIFF_DEFAULT_DURATION,\r
- G_PARAM_READWRITE));\r
-\r
- g_object_class_install_property (gobject_class, PROP_PIFF_MEDIA_START_TIMESTAMP,\r
- g_param_spec_uint64 ("start-ts", "expected start timestamp",\r
- "expected start timestamp to avoid reset", 0, G_MAXUINT64,\r
- PIFF_DEFAULT_START_TS,\r
- G_PARAM_READWRITE));\r
-\r
- g_object_class_install_property (gobject_class, PROP_PIFF_IS_LIVE,\r
- g_param_spec_boolean ("is-live", "Is presentation is Live or VOD",\r
- "If Presentation is Live (true) else VOD (false)",\r
- FALSE,\r
- G_PARAM_READWRITE));\r
-\r
- g_object_class_install_property (gobject_class, PROP_PIFF_LOOKAHEAD_COUNT,\r
- g_param_spec_uint ("lookahead-count", "Lookahead count value",\r
- "Look ahead count used in case of Live presentation", 0, G_MAXUINT,\r
- 0,\r
- G_PARAM_READWRITE));\r
-\r
- g_object_class_install_property (gobject_class, PROP_PIFF_AVG_FRAME_DUR,\r
- g_param_spec_uint64 ("frame-dur", "Average frame duration",\r
- "Average frame duration", 0, G_MAXUINT64,\r
- G_MAXUINT64,\r
- G_PARAM_READABLE));\r
-\r
- gst_piffdemux_signals[SIGNAL_LIVE_PARAM] =\r
- g_signal_new ("live-param", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,\r
- G_STRUCT_OFFSET (GstPiffDemuxClass, live_param), NULL, NULL,\r
- g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE, 1, G_TYPE_POINTER);\r
-\r
-}\r
-\r
-static void\r
-gst_piffdemux_init (GstPiffDemux * piffdemux, GstPiffDemuxClass * klass)\r
-{\r
- /* sink pad */\r
- piffdemux->sinkpad = gst_pad_new_from_static_template (&gst_piffdemux_sink_template, "sink");\r
- gst_pad_set_chain_function (piffdemux->sinkpad, gst_piffdemux_chain);\r
- gst_pad_set_event_function (piffdemux->sinkpad, gst_piffdemux_handle_sink_event);\r
- gst_element_add_pad (GST_ELEMENT_CAST (piffdemux), piffdemux->sinkpad);\r
-\r
- /* source pad */\r
- piffdemux->srcpad = gst_pad_new_from_static_template (&gst_piffdemux_src_template, "src");\r
- gst_pad_set_event_function (piffdemux->srcpad, gst_piffdemux_handle_src_event);\r
- gst_pad_use_fixed_caps (piffdemux->srcpad);\r
- gst_pad_set_query_type_function (piffdemux->srcpad, gst_piffdemux_get_src_query_types);\r
- gst_pad_set_query_function (piffdemux->srcpad, gst_piffdemux_handle_src_query);\r
- gst_element_add_pad (GST_ELEMENT_CAST (piffdemux), piffdemux->srcpad);\r
-\r
- piffdemux->stream = g_new0 (PiffDemuxStream, 1);\r
- piffdemux->stream->fourcc = PIFF_DEFAULT_FOURCC;\r
- piffdemux->stream->timescale = PIFF_DEFAULT_TIMESCALE;\r
- piffdemux->stream->duration = PIFF_DEFAULT_DURATION;\r
- piffdemux->stream->caps = NULL;\r
- piffdemux->stream->discont = TRUE;\r
- piffdemux->stream->need_process = FALSE;\r
- piffdemux->stream->segment_index = -1;\r
- piffdemux->stream->time_position = 0;\r
- piffdemux->stream->sample_index = -1;\r
- piffdemux->stream->last_ret = GST_FLOW_OK;\r
- piffdemux->stream->sent_nsevent = FALSE;\r
- piffdemux->stream->start_ts = PIFF_DEFAULT_START_TS;\r
- piffdemux->stream->avg_dur = -1;\r
-\r
- piffdemux->state = PIFFDEMUX_STATE_INITIAL;\r
- piffdemux->neededbytes = 16;\r
- piffdemux->todrop = 0;\r
- piffdemux->adapter = gst_adapter_new ();\r
- piffdemux->offset = 0;\r
- piffdemux->first_mdat = -1;\r
- piffdemux->mdatoffset = GST_CLOCK_TIME_NONE;\r
- piffdemux->mdatbuffer = NULL;\r
- piffdemux->moof_rcvd = FALSE;\r
- piffdemux->is_live = FALSE;\r
- piffdemux->lookahead_cnt = 0;\r
-\r
-#ifdef DEC_OUT_FRAME_DUMP\r
- piffdump = fopen ("/opt/media/piff_out_dump.dmp", "w+");\r
- if (piffdump == NULL)\r
- {\r
- g_print ("\nNot able to create frame dump file\n");\r
- }\r
-#endif\r
-\r
- gst_segment_init (&piffdemux->segment, GST_FORMAT_TIME);\r
-}\r
-\r
-static void\r
-gst_piffdemux_dispose (GObject * object)\r
-{\r
- GstPiffDemux *piffdemux = GST_PIFFDEMUX (object);\r
-\r
- if (piffdemux->adapter) {\r
- g_object_unref (G_OBJECT (piffdemux->adapter));\r
- piffdemux->adapter = NULL;\r
- }\r
-\r
-#ifdef DEC_OUT_FRAME_DUMP\r
- {\r
- fclose (piffdump);\r
- piffdump = NULL;\r
- }\r
-#endif\r
- G_OBJECT_CLASS (parent_class)->dispose (object);\r
-}\r
-\r
-\r
-static void\r
-gst_piffdemux_set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)\r
-{\r
- GstPiffDemux *piffdemux = GST_PIFFDEMUX (object);\r
-\r
- switch (prop_id) {\r
- case PROP_PIFF_MEDIA_CAPS: {\r
- if (piffdemux->stream->caps)\r
- gst_caps_unref(piffdemux->stream->caps);\r
- piffdemux->stream->caps = gst_caps_copy (gst_value_get_caps (value));\r
- GST_DEBUG_OBJECT (piffdemux, "stream caps = %s", gst_caps_to_string(piffdemux->stream->caps));\r
- if (!gst_pad_set_caps(piffdemux->srcpad, piffdemux->stream->caps)) {\r
- GST_ERROR_OBJECT (piffdemux, "not able to set caps...");\r
- }\r
- break;\r
- }\r
- case PROP_PIFF_MEDIA_TIMESCALE:\r
- piffdemux->stream->timescale = g_value_get_uint64(value);\r
- break;\r
- case PROP_PIFF_MEDIA_DURATION:\r
- piffdemux->stream->duration = g_value_get_int64(value);\r
- break;\r
- case PROP_PIFF_MEDIA_START_TIMESTAMP:\r
- piffdemux->stream->start_ts = g_value_get_uint64(value);\r
- GST_INFO_OBJECT (piffdemux, "start_ts = %"GST_TIME_FORMAT, GST_TIME_ARGS(piffdemux->stream->start_ts));\r
- break;\r
- case PROP_PIFF_IS_LIVE:\r
- piffdemux->is_live = g_value_get_boolean(value);\r
- break;\r
- case PROP_PIFF_LOOKAHEAD_COUNT:\r
- piffdemux->lookahead_cnt = g_value_get_uint(value);\r
- GST_DEBUG_OBJECT (piffdemux, "Look ahead count = %d", piffdemux->lookahead_cnt);\r
- break;\r
- default:\r
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);\r
- break;\r
- }\r
-}\r
-\r
-\r
-static void\r
-gst_piffdemux_get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)\r
-{\r
- GstPiffDemux *piffdemux = GST_PIFFDEMUX (object);\r
-\r
- switch (prop_id) {\r
- case PROP_PIFF_MEDIA_CAPS:\r
- gst_value_set_caps (value, piffdemux->stream->caps);\r
- break;\r
- case PROP_PIFF_MEDIA_TIMESCALE:\r
- g_value_set_uint64 (value, piffdemux->stream->timescale);\r
- break;\r
- case PROP_PIFF_MEDIA_DURATION:\r
- g_value_set_int64 (value, piffdemux->stream->duration);\r
- break;\r
- case PROP_PIFF_MEDIA_START_TIMESTAMP:\r
- g_value_set_uint64 (value, piffdemux->stream->start_ts);\r
- break;\r
- case PROP_PIFF_IS_LIVE:\r
- g_value_set_boolean(value, piffdemux->is_live);\r
- break;\r
- case PROP_PIFF_LOOKAHEAD_COUNT:\r
- g_value_set_uint (value, piffdemux->lookahead_cnt);\r
- break;\r
- case PROP_PIFF_AVG_FRAME_DUR:\r
- g_value_set_uint64 (value, piffdemux->stream->avg_dur);\r
- break;\r
- default:\r
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);\r
- break;\r
- }\r
-}\r
-\r
-\r
-static void\r
-gst_piffdemux_post_no_playable_stream_error (GstPiffDemux * piffdemux)\r
-{\r
- if (piffdemux->posted_redirect) {\r
- GST_ELEMENT_ERROR (piffdemux, STREAM, DEMUX,\r
- ("This file contains no playable streams."),\r
- ("no known streams found, a redirect message has been posted"));\r
- } else {\r
- GST_ELEMENT_ERROR (piffdemux, STREAM, DEMUX,\r
- ("This file contains no playable streams."),\r
- ("no known streams found"));\r
- }\r
-\r
-}\r
-\r
-static gboolean\r
-gst_piffdemux_src_convert (GstPad * pad, GstFormat src_format, gint64 src_value,\r
- GstFormat dest_format, gint64 * dest_value)\r
-{\r
- gboolean res = TRUE;\r
- PiffDemuxStream *stream = gst_pad_get_element_private (pad);\r
- GstPiffDemux *piffdemux = GST_PIFFDEMUX (gst_pad_get_parent (pad));\r
-\r
- if (stream->subtype != FOURCC_vide) {\r
- res = FALSE;\r
- goto done;\r
- }\r
-\r
- switch (src_format) {\r
- case GST_FORMAT_TIME:\r
- switch (dest_format) {\r
- case GST_FORMAT_BYTES:{\r
-\r
- break;\r
- }\r
- default:\r
- res = FALSE;\r
- break;\r
- }\r
- break;\r
- case GST_FORMAT_BYTES:\r
- switch (dest_format) {\r
- case GST_FORMAT_TIME:{\r
-\r
- break;\r
- }\r
- default:\r
- res = FALSE;\r
- break;\r
- }\r
- break;\r
- default:\r
- res = FALSE;\r
- }\r
-\r
-done:\r
- gst_object_unref (piffdemux);\r
-\r
- return res;\r
-}\r
-\r
-static const GstQueryType *\r
-gst_piffdemux_get_src_query_types (GstPad * pad)\r
-{\r
- static const GstQueryType src_types[] = {\r
- GST_QUERY_POSITION,\r
- GST_QUERY_DURATION,\r
- GST_QUERY_CONVERT,\r
- GST_QUERY_FORMATS,\r
- GST_QUERY_SEEKING,\r
- 0\r
- };\r
-\r
- return src_types;\r
-}\r
-\r
-static gboolean\r
-gst_piffdemux_get_duration (GstPiffDemux * piffdemux, gint64 * duration)\r
-{\r
- gboolean res = TRUE;\r
-\r
- *duration = GST_CLOCK_TIME_NONE;\r
-\r
- if (piffdemux->stream->duration != 0) {\r
- if (piffdemux->stream->duration != G_MAXINT64 && piffdemux->stream->timescale != 0) {\r
- *duration = gst_util_uint64_scale (piffdemux->stream->duration,\r
- GST_SECOND, piffdemux->stream->timescale);\r
- }\r
- }\r
- return res;\r
-}\r
-\r
-static gboolean\r
-gst_piffdemux_handle_src_query (GstPad * pad, GstQuery * query)\r
-{\r
- gboolean res = FALSE;\r
- GstPiffDemux *piffdemux = GST_PIFFDEMUX (gst_pad_get_parent (pad));\r
-\r
- GST_LOG_OBJECT (pad, "%s query", GST_QUERY_TYPE_NAME (query));\r
-\r
- switch (GST_QUERY_TYPE (query)) {\r
- case GST_QUERY_POSITION:\r
- GST_ERROR ("Querying POSITION from piffdemux....");\r
- if (GST_CLOCK_TIME_IS_VALID (piffdemux->segment.last_stop)) {\r
- gst_query_set_position (query, GST_FORMAT_TIME,\r
- piffdemux->segment.last_stop);\r
- res = TRUE;\r
- }\r
- break;\r
- case GST_QUERY_DURATION:{\r
- GstFormat fmt;\r
- GST_ERROR ("Querying DURATION from piffdemux....");\r
-\r
- gst_query_parse_duration (query, &fmt, NULL);\r
- if (fmt == GST_FORMAT_TIME) {\r
- gint64 duration = -1;\r
-\r
- gst_piffdemux_get_duration (piffdemux, &duration);\r
- if (duration > 0) {\r
- gst_query_set_duration (query, GST_FORMAT_TIME, duration);\r
- res = TRUE;\r
- }\r
- }\r
- break;\r
- }\r
- case GST_QUERY_CONVERT:{\r
- GstFormat src_fmt, dest_fmt;\r
- gint64 src_value, dest_value = 0;\r
-\r
- gst_query_parse_convert (query, &src_fmt, &src_value, &dest_fmt, NULL);\r
-\r
- res = gst_piffdemux_src_convert (pad,\r
- src_fmt, src_value, dest_fmt, &dest_value);\r
- if (res) {\r
- gst_query_set_convert (query, src_fmt, src_value, dest_fmt, dest_value);\r
- res = TRUE;\r
- }\r
- break;\r
- }\r
- case GST_QUERY_FORMATS:\r
- gst_query_set_formats (query, 2, GST_FORMAT_TIME, GST_FORMAT_BYTES);\r
- res = TRUE;\r
- break;\r
- case GST_QUERY_SEEKING:{\r
-\r
- break;\r
- }\r
- default:\r
- res = gst_pad_query_default (pad, query);\r
- break;\r
- }\r
-\r
- gst_object_unref (piffdemux);\r
-\r
- return res;\r
-}\r
-\r
-\r
-static void\r
-gst_piffdemux_push_tags (GstPiffDemux * piffdemux, PiffDemuxStream * stream)\r
-{\r
- if (G_UNLIKELY (stream->pending_tags)) {\r
- GST_DEBUG_OBJECT (piffdemux, "Sending tags %" GST_PTR_FORMAT,\r
- stream->pending_tags);\r
- gst_pad_push_event (piffdemux->srcpad,\r
- gst_event_new_tag (stream->pending_tags));\r
- stream->pending_tags = NULL;\r
- }\r
-\r
- if (G_UNLIKELY (stream->send_global_tags && piffdemux->tag_list)) {\r
- GST_DEBUG_OBJECT (piffdemux, "Sending global tags %" GST_PTR_FORMAT,\r
- piffdemux->tag_list);\r
- gst_pad_push_event (piffdemux->srcpad,\r
- gst_event_new_tag (gst_tag_list_copy (piffdemux->tag_list)));\r
- stream->send_global_tags = FALSE;\r
- }\r
-}\r
-\r
-\r
-static void\r
-gst_piffdemux_push_event (GstPiffDemux * piffdemux, GstEvent * event)\r
-{\r
- GstEventType etype = GST_EVENT_TYPE (event);\r
-\r
- GST_DEBUG_OBJECT (piffdemux, "pushing %s event on source pad",\r
- GST_EVENT_TYPE_NAME (event));\r
-\r
- if (piffdemux->stream->sent_eos) {\r
- GST_INFO_OBJECT (piffdemux, "already sent eos");\r
- return;\r
- }\r
-\r
- if (!gst_pad_push_event (piffdemux->srcpad, event)) {\r
- GST_ERROR_OBJECT (piffdemux, "error in sending event to srcpad...");\r
- }\r
-\r
- if (etype == GST_EVENT_EOS)\r
- piffdemux->stream->sent_eos = TRUE;\r
-}\r
-\r
-\r
-/* find the segment for @time_position for @stream\r
- *\r
- * Returns -1 if the segment cannot be found.\r
- */\r
-static guint32\r
-gst_piffdemux_find_segment (GstPiffDemux * piffdemux, PiffDemuxStream * stream,\r
- guint64 time_position)\r
-{\r
- gint i;\r
- guint32 seg_idx;\r
-\r
- GST_LOG_OBJECT (piffdemux, "finding segment for %" GST_TIME_FORMAT,\r
- GST_TIME_ARGS (time_position));\r
-\r
- /* find segment corresponding to time_position if we are looking\r
- * for a segment. */\r
- seg_idx = -1;\r
- for (i = 0; i < stream->n_segments; i++) {\r
- PiffDemuxSegment *segment = &stream->segments[i];\r
-\r
- GST_LOG_OBJECT (piffdemux,\r
- "looking at segment %" GST_TIME_FORMAT "-%" GST_TIME_FORMAT,\r
- GST_TIME_ARGS (segment->time), GST_TIME_ARGS (segment->stop_time));\r
-\r
- /* For the last segment we include stop_time in the last segment */\r
- if (i < stream->n_segments - 1) {\r
- if (segment->time <= time_position && time_position < segment->stop_time) {\r
- GST_LOG_OBJECT (piffdemux, "segment %d matches", i);\r
- seg_idx = i;\r
- break;\r
- }\r
- } else {\r
- if (segment->time <= time_position && time_position <= segment->stop_time) {\r
- GST_LOG_OBJECT (piffdemux, "segment %d matches", i);\r
- seg_idx = i;\r
- break;\r
- }\r
- }\r
- }\r
- return seg_idx;\r
-}\r
-\r
-\r
-static gboolean\r
-gst_piffdemux_handle_src_event (GstPad * pad, GstEvent * event)\r
-{\r
- gboolean res = TRUE;\r
- GstPiffDemux *piffdemux = GST_PIFFDEMUX (gst_pad_get_parent (pad));\r
-\r
- switch (GST_EVENT_TYPE (event)) {\r
- case GST_EVENT_QOS:\r
- case GST_EVENT_NAVIGATION:\r
- res = FALSE;\r
- gst_event_unref (event);\r
- break;\r
- case GST_EVENT_SEEK:\r
- default:\r
- res = gst_pad_event_default (pad, event);\r
- break;\r
- }\r
-\r
- gst_object_unref (piffdemux);\r
-\r
- return res;\r
-}\r
-\r
-\r
-static void\r
-gst_piffdemux_move_stream (GstPiffDemux * piffdemux, PiffDemuxStream * str,\r
- guint32 index)\r
-{\r
- /* no change needed */\r
- if (index == str->sample_index)\r
- return;\r
-\r
- GST_DEBUG_OBJECT (piffdemux, "moving to sample %u of %u", index,\r
- str->n_samples);\r
-\r
- /* position changed, we have a discont */\r
- str->sample_index = index;\r
- /* Each time we move in the stream we store the position where we are\r
- * starting from */\r
- str->from_sample = index;\r
- str->discont = TRUE;\r
-}\r
-\r
-// TODO: need to check more on this below function\r
-/* stream/index return sample that is min/max w.r.t. byte position,\r
- * time is min/max w.r.t. time of samples,\r
- * the latter need not be time of the former sample */\r
-static void\r
-gst_piffdemux_find_sample (GstPiffDemux * piffdemux, gint64 byte_pos, gboolean fw,\r
- gboolean set, PiffDemuxStream ** _stream, gint * _index, gint64 * _time)\r
-{\r
- gint i, index;\r
- gint64 time, min_time;\r
- PiffDemuxStream *stream;\r
- PiffDemuxStream *str = piffdemux->stream;\r
- gint inc;\r
- gboolean set_sample;\r
-\r
- min_time = -1;\r
- stream = NULL;\r
- index = -1;\r
-\r
- set_sample = !set;\r
- if (fw) {\r
- i = 0;\r
- inc = 1;\r
- } else {\r
- i = str->n_samples - 1;\r
- inc = -1;\r
- }\r
-\r
- for (; (i >= 0) && (i < str->n_samples); i += inc) {\r
- if (str->samples[i].size &&\r
- ((fw && (str->samples[i].offset >= byte_pos)) ||\r
- (!fw &&\r
- (str->samples[i].offset + str->samples[i].size <=\r
- byte_pos)))) {\r
- /* move stream to first available sample */\r
- if (set) {\r
- gst_piffdemux_move_stream (piffdemux, str, i);\r
- set_sample = TRUE;\r
- }\r
- /* determine min/max time */\r
- time = str->samples[i].timestamp + str->samples[i].pts_offset;\r
- time = gst_util_uint64_scale (time, GST_SECOND, str->timescale);\r
- if (min_time == -1 || (!fw && time > min_time) ||\r
- (fw && time < min_time)) {\r
- min_time = time;\r
- }\r
- index = i;\r
- break;\r
- }\r
- }\r
- /* no sample for this stream, mark eos */\r
- if (!set_sample)\r
- gst_piffdemux_move_stream (piffdemux, str, str->n_samples);\r
-\r
- if (_time)\r
- *_time = min_time;\r
- if (_stream)\r
- *_stream = str;\r
- if (_index)\r
- *_index = index;\r
-}\r
-\r
-\r
-static gboolean\r
-gst_piffdemux_handle_sink_event (GstPad * sinkpad, GstEvent * event)\r
-{\r
- GstPiffDemux *demux = GST_PIFFDEMUX (GST_PAD_PARENT (sinkpad));\r
- gboolean res;\r
-\r
- GST_LOG_OBJECT (demux, "handling %s event", GST_EVENT_TYPE_NAME (event));\r
-\r
- switch (GST_EVENT_TYPE (event)) {\r
- case GST_EVENT_NEWSEGMENT:\r
- {\r
- GstFormat format;\r
- gdouble rate, arate;\r
- gint64 start, stop, time, offset = 0;\r
- PiffDemuxStream *stream;\r
- gint idx;\r
- gboolean update;\r
- GstSegment segment;\r
-\r
- /* some debug output */\r
- gst_segment_init (&segment, GST_FORMAT_UNDEFINED);\r
- gst_event_parse_new_segment_full (event, &update, &rate, &arate, &format,\r
- &start, &stop, &time);\r
- gst_segment_set_newsegment_full (&segment, update, rate, arate, format,\r
- start, stop, time);\r
- GST_ERROR_OBJECT (demux,\r
- "received format %d newsegment %" GST_SEGMENT_FORMAT, format,\r
- &segment);\r
-\r
- /* chain will send initial newsegment after pads have been added */\r
- if (demux->state != PIFFDEMUX_STATE_MOVIE ) {\r
- GST_DEBUG_OBJECT (demux, "still starting, eating event");\r
- goto exit;\r
- }\r
-\r
- /* we only expect a BYTE segment, e.g. following a seek */\r
- if (format == GST_FORMAT_BYTES) {\r
- if (start > 0) {\r
- gint64 requested_seek_time;\r
- guint64 seek_offset;\r
-\r
- offset = start;\r
-\r
- GST_OBJECT_LOCK (demux);\r
- requested_seek_time = demux->requested_seek_time;\r
- seek_offset = demux->seek_offset;\r
- demux->requested_seek_time = -1;\r
- demux->seek_offset = -1;\r
- GST_OBJECT_UNLOCK (demux);\r
-\r
- if (offset == seek_offset) {\r
- start = requested_seek_time;\r
- } else {\r
- gst_piffdemux_find_sample (demux, start, TRUE, FALSE, NULL, NULL,\r
- &start);\r
- start = MAX (start, 0);\r
- }\r
- }\r
- if (stop > 0) {\r
- gst_piffdemux_find_sample (demux, stop, FALSE, FALSE, NULL, NULL,\r
- &stop);\r
- /* keyframe seeking should already arrange for start >= stop,\r
- * but make sure in other rare cases */\r
- stop = MAX (stop, start);\r
- }\r
- }\r
-#if 0\r
- else if (format == GST_FORMAT_TIME) {\r
- // Supporting TIME_FORMAT for new_segment\r
- //gst_piffdemux_push_event (demux,event);\r
- PiffDemuxStream *stream = NULL;\r
- int i = -1;\r
-\r
- demux->neededbytes = 16;\r
- demux->state = PIFFDEMUX_STATE_INITIAL;\r
- demux->offset = 0;\r
-\r
- /* Figure out which stream this is packet belongs to */\r
- for (i = 0; i < demux->n_streams; i++) {\r
- stream = demux->streams[i];\r
- stream->last_ts = start;\r
- stream->discont = TRUE;\r
- stream->sample_index = stream->n_samples;\r
- }\r
-\r
- /* accept upstream's notion of segment and distribute along */\r
- gst_segment_set_newsegment_full (&demux->segment, update, rate, arate,\r
- GST_FORMAT_TIME, start, stop, start);\r
- GST_ERROR_OBJECT (demux, "Pushing newseg update %d, rate %g, "\r
- "applied rate %g, format %d, start %" GST_TIME_FORMAT ", "\r
- "stop %" GST_TIME_FORMAT, update, rate, arate, GST_FORMAT_TIME,\r
- GST_TIME_ARGS (start), GST_TIME_ARGS (stop));\r
-\r
- gst_piffdemux_push_event (demux,\r
- gst_event_new_new_segment_full (update, rate, arate, GST_FORMAT_TIME, start, stop, start));\r
-\r
- /* clear leftover in current segment, if any */\r
- gst_adapter_clear (demux->adapter);\r
-\r
- goto exit;\r
- }\r
-#endif\r
- else {\r
- GST_DEBUG_OBJECT (demux, "unsupported segment format, ignoring");\r
- goto exit;\r
- }\r
-\r
- /* accept upstream's notion of segment and distribute along */\r
- gst_segment_set_newsegment_full (&demux->segment, update, rate, arate,\r
- GST_FORMAT_TIME, start, stop, start);\r
- GST_ERROR_OBJECT (demux, "Pushing newseg update %d, rate %g, "\r
- "applied rate %g, format %d, start %" GST_TIME_FORMAT ", "\r
- "stop %" GST_TIME_FORMAT, update, rate, arate, GST_FORMAT_TIME,\r
- GST_TIME_ARGS (start), GST_TIME_ARGS (stop));\r
-\r
- gst_piffdemux_push_event (demux,\r
- gst_event_new_new_segment_full (update, rate, arate, GST_FORMAT_TIME,\r
- start, stop, start));\r
-\r
- /* clear leftover in current segment, if any */\r
- gst_adapter_clear (demux->adapter);\r
- /* set up streaming thread */\r
- gst_piffdemux_find_sample (demux, offset, TRUE, TRUE, &stream, &idx, NULL);\r
- demux->offset = offset;\r
- if (stream) {\r
- demux->todrop = stream->samples[idx].offset - offset;\r
- demux->neededbytes = demux->todrop + stream->samples[idx].size;\r
- } else {\r
- /* set up for EOS */\r
- demux->neededbytes = -1;\r
- demux->todrop = 0;\r
- }\r
- exit:\r
- gst_event_unref (event);\r
- res = TRUE;\r
- goto drop;\r
- break;\r
- }\r
- case GST_EVENT_FLUSH_STOP:\r
- {\r
- /* clean up, force EOS if no more info follows */\r
- gst_adapter_clear (demux->adapter);\r
- demux->offset = 0;\r
- demux->neededbytes = -1;\r
- /* reset flow return, e.g. following seek */\r
- demux->stream->last_ret = GST_FLOW_OK;\r
- demux->stream->sent_eos = FALSE;\r
- break;\r
- }\r
- case GST_EVENT_EOS:\r
- break;\r
- default:\r
- break;\r
- }\r
-\r
- res = gst_pad_event_default (demux->sinkpad, event);\r
-\r
-drop:\r
- return res;\r
-}\r
-\r
-\r
-static void\r
-gst_piffdemux_stream_free (GstPiffDemux * piffdemux, PiffDemuxStream * stream)\r
-{\r
- while (stream->buffers) {\r
- gst_buffer_unref (GST_BUFFER_CAST (stream->buffers->data));\r
- stream->buffers = g_slist_delete_link (stream->buffers, stream->buffers);\r
- }\r
- g_free (stream->samples);\r
- if (stream->caps)\r
- gst_caps_unref (stream->caps);\r
- g_free (stream->segments);\r
- if (stream->pending_tags)\r
- gst_tag_list_free (stream->pending_tags);\r
- g_free (stream);\r
-}\r
-\r
-\r
-static GstStateChangeReturn\r
-gst_piffdemux_change_state (GstElement * element, GstStateChange transition)\r
-{\r
- GstPiffDemux *piffdemux = GST_PIFFDEMUX (element);\r
- GstStateChangeReturn result = GST_STATE_CHANGE_FAILURE;\r
-\r
- switch (transition) {\r
- case GST_STATE_CHANGE_PAUSED_TO_READY:\r
- break;\r
- default:\r
- break;\r
- }\r
-\r
- result = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);\r
-\r
- switch (transition) {\r
- case GST_STATE_CHANGE_PAUSED_TO_READY:{\r
- piffdemux->state = PIFFDEMUX_STATE_INITIAL;\r
- piffdemux->neededbytes = 16;\r
- piffdemux->todrop = 0;\r
- piffdemux->posted_redirect = FALSE;\r
- piffdemux->offset = 0;\r
- piffdemux->first_mdat = -1;\r
- piffdemux->mdatoffset = GST_CLOCK_TIME_NONE;\r
- if (piffdemux->mdatbuffer)\r
- gst_buffer_unref (piffdemux->mdatbuffer);\r
- piffdemux->mdatbuffer = NULL;\r
- if (piffdemux->tag_list)\r
- gst_tag_list_free (piffdemux->tag_list);\r
- piffdemux->tag_list = NULL;\r
- gst_adapter_clear (piffdemux->adapter);\r
- gst_segment_init (&piffdemux->segment, GST_FORMAT_TIME);\r
- break;\r
- }\r
- default:\r
- break;\r
- }\r
-\r
- return result;\r
-}\r
-\r
-static void\r
-piffdemux_post_global_tags (GstPiffDemux * piffdemux)\r
-{\r
- if (piffdemux->tag_list) {\r
- /* all header tags ready and parsed, push them */\r
- GST_INFO_OBJECT (piffdemux, "posting global tags: %" GST_PTR_FORMAT,\r
- piffdemux->tag_list);\r
- /* post now, send event on pads later */\r
- gst_element_post_message (GST_ELEMENT (piffdemux),\r
- gst_message_new_tag (GST_OBJECT (piffdemux),\r
- gst_tag_list_copy (piffdemux->tag_list)));\r
- }\r
-}\r
-\r
-\r
-/* caller verifies at least 8 bytes in buf */\r
-static void\r
-extract_initial_length_and_fourcc (const guint8 * data, guint size,\r
- guint64 * plength, guint32 * pfourcc)\r
-{\r
- guint64 length;\r
- guint32 fourcc;\r
-\r
- length = PIFF_UINT32 (data);\r
- GST_DEBUG ("length 0x%08" G_GINT64_MODIFIER "x", length);\r
- fourcc = PIFF_FOURCC (data + 4);\r
- GST_DEBUG ("atom type %" GST_FOURCC_FORMAT, GST_FOURCC_ARGS (fourcc));\r
-\r
- if (length == 0) {\r
- length = G_MAXUINT32;\r
- } else if (length == 1 && size >= 16) {\r
- /* this means we have an extended size, which is the 64 bit value of\r
- * the next 8 bytes */\r
- length = PIFF_UINT64 (data + 8);\r
- GST_DEBUG ("length 0x%08" G_GINT64_MODIFIER "x", length);\r
- }\r
-\r
- if (plength)\r
- *plength = length;\r
- if (pfourcc)\r
- *pfourcc = fourcc;\r
-}\r
-\r
-static gboolean\r
-piffdemux_update_sample_offset (GstPiffDemux * piffdemu, PiffDemuxStream * stream, gint64 uuid_offset)\r
-{\r
- PiffDemuxSample *sample;\r
- gint i;\r
-\r
- sample = stream->samples ;\r
- for (i = 0; i < stream->n_samples; i++)\r
- {\r
- sample->offset = sample->offset + uuid_offset;\r
- sample++;\r
- }\r
- return TRUE;\r
-}\r
-\r
-static uuid_type_t\r
-piffdemux_get_uuid_type(GstPiffDemux * piffdemux, GstByteReader *uuid_data, gint64 *uuid_offset)\r
-{\r
- uuid_type_t uuid_type = UUID_UNKNOWN;\r
- guint32 box_len = 0;\r
- guint64 box_long_len = 0;\r
- gchar uuid[16] = {0,};\r
- int i = 0;\r
-\r
- if (!gst_byte_reader_get_uint32_be (uuid_data, &box_len))\r
- goto invalid_uuid;\r
-\r
- /* Skipping fourcc */\r
- if (!gst_byte_reader_skip (uuid_data, 4))\r
- goto invalid_uuid;\r
-\r
- if (box_len == 1)\r
- {\r
- GST_WARNING ("TfxdBoxLongLength field is present...");\r
- if (!gst_byte_reader_get_uint64_be (uuid_data, &box_long_len))\r
- goto invalid_uuid;\r
- GST_DEBUG ("tfxd long length = %llu", box_long_len);\r
-\r
- *uuid_offset = box_long_len;\r
- }\r
- else\r
- {\r
- GST_DEBUG ("Box Len = %d", box_len);\r
- *uuid_offset = box_len;\r
- }\r
-\r
- //g_print ("\n\n\n 0x");\r
- for (i = 0; i < sizeof (uuid); i++)\r
- {\r
- if (!gst_byte_reader_get_uint8 (uuid_data, &(uuid[i])))\r
- goto invalid_uuid;\r
- //g_print ("%02x", uuid[i]);\r
- }\r
- //g_print ("\n\n\n");\r
-\r
- if (!memcmp(uuid, tfxd_uuid, sizeof (uuid_t)))\r
- {\r
- GST_INFO ("Found TFXD box");\r
- return UUID_TFXD;\r
- }\r
- else if (!memcmp(uuid, tfrf_uuid, sizeof (uuid_t)))\r
- {\r
- GST_INFO ("Found TFRF box");\r
- return UUID_TFRF;\r
- }\r
- else if (!memcmp(uuid, encrypt_uuid, sizeof (uuid_t)))\r
- {\r
- GST_INFO ("Found sample encryption box");\r
- return UUID_SAMPLE_ENCRYPT;\r
- }\r
- else\r
- {\r
- GST_WARNING ("Not an valid UUID box..");\r
- goto invalid_uuid;\r
- }\r
- return uuid_type;\r
-\r
-invalid_uuid:\r
- GST_ERROR ("Error in parsing UUID atom...");\r
- return UUID_UNKNOWN;\r
-}\r
-\r
-static gboolean\r
-piffdemux_parse_sample_encryption(GstPiffDemux * piffdemux, GstByteReader *sample_encrypt, PiffDemuxStream * stream)\r
-{\r
- guint32 flags = 0;\r
- guint32 sample_count = 0;\r
- guint32 i = 0;\r
- guint32 algo_id;\r
- guint8 iv_size = 0;\r
-\r
- if (!gst_byte_reader_skip (sample_encrypt, 1) ||\r
- !gst_byte_reader_get_uint24_be (sample_encrypt, &flags))\r
- goto invalid_encryption;\r
-\r
- if (flags & SE_OVERRIDE_TE_FLAGS) {\r
- /* get algorithm id */\r
- if (!gst_byte_reader_get_uint32_be (sample_encrypt, &algo_id))\r
- goto invalid_encryption;\r
-\r
- /* get IV size */\r
- if (!gst_byte_reader_get_uint8 (sample_encrypt, &iv_size))\r
- goto invalid_encryption;\r
-\r
- // TODO: need to add reading of KID\r
- } else {\r
- GST_INFO_OBJECT (piffdemux, "Override flags are not present... taking default IV_Size = 8");\r
- iv_size = 8;\r
- }\r
-\r
- /* Get sample count*/\r
- if (!gst_byte_reader_get_uint32_be (sample_encrypt, &sample_count))\r
- goto invalid_encryption;\r
-\r
- GST_INFO_OBJECT (piffdemux, "Sample count = %d", sample_count);\r
-\r
- if (sample_count != stream->n_samples) {\r
- GST_ERROR_OBJECT (piffdemux, "Not all samples has IV vectors... Don't know how to handle. sample_cnt = %d and stream->n_samples = %d",\r
- sample_count, stream->n_samples);\r
- goto invalid_encryption;\r
- }\r
-\r
- for (i = 0; i < stream->n_samples; i++) {\r
- guint8 iv_idx = iv_size;\r
-\r
- /* resetting entire IV array */\r
- stream->samples[i].iv = (guint8 *)malloc (iv_size);\r
- if (NULL == stream->samples[i].iv) {\r
- GST_ERROR ("Failed to allocate memory...\n");\r
- goto invalid_encryption;\r
- }\r
-\r
- memset (stream->samples[i].iv, 0x00, iv_size);\r
-\r
- iv_idx = 0;\r
- while (iv_idx < iv_size) {\r
- /* get IV byte */\r
- if (!gst_byte_reader_get_uint8 (sample_encrypt, &(stream->samples[i].iv[iv_idx])))\r
- goto invalid_encryption;\r
-\r
- iv_idx++;\r
- }\r
-\r
-#ifdef DEBUG_IV\r
- {\r
- guint8 tmp_idx = 0;\r
- g_print ("sample[%d] : 0x ", i);\r
-\r
- while (tmp_idx < iv_size ) {\r
- g_print ("%02x ", stream->samples[i].iv[tmp_idx]);\r
- tmp_idx++;\r
- }\r
- g_print ("\n");\r
- }\r
-#endif\r
-\r
- if (flags & SE_USE_SUBSAMPLE_ENCRYPTION) {\r
- guint16 n_entries;\r
- guint16 n_idx;\r
-\r
- /* NumberofEntries in SubSampleEncryption */\r
- if (!gst_byte_reader_get_uint16_be (sample_encrypt, &n_entries))\r
- goto invalid_encryption;\r
-\r
- stream->samples[i].sub_encry = (PiffDemuxSubSampleEncryption *)malloc (sizeof (PiffDemuxSubSampleEncryption));\r
- if (NULL == stream->samples[i].sub_encry) {\r
- GST_ERROR ("Failed to allocate memory...\n");\r
- goto invalid_encryption;\r
- }\r
-\r
- stream->samples[i].sub_encry->sub_entry = g_try_new0 (PiffDemuxSubSampleEntryInfo, n_entries);\r
- if (NULL == stream->samples[i].sub_encry->sub_entry)\r
- {\r
- GST_ERROR_OBJECT (piffdemux, "Failed to allocate memory...");\r
- goto invalid_encryption;\r
- }\r
-\r
- stream->samples[i].sub_encry->n_entries = n_entries;\r
-\r
- GST_DEBUG_OBJECT (piffdemux,"No. of subsample entries = %d", stream->samples[i].sub_encry->n_entries);\r
-\r
- for (n_idx = 0; n_idx < n_entries; n_idx++) {\r
- if (!gst_byte_reader_get_uint16_be (sample_encrypt, &(stream->samples[i].sub_encry->sub_entry[n_idx].LenofClearData)))\r
- goto invalid_encryption;\r
-\r
- GST_DEBUG_OBJECT (piffdemux,"entry[%d] and lengthofClearData = %d", n_idx, stream->samples[i].sub_encry->sub_entry[n_idx].LenofClearData);\r
-\r
- if (!gst_byte_reader_get_uint32_be (sample_encrypt, &(stream->samples[i].sub_encry->sub_entry[n_idx].LenofEncryptData)))\r
- goto invalid_encryption;\r
-\r
- GST_DEBUG_OBJECT (piffdemux,"entry[%d] and lengthofEncryptData = %d", n_idx, stream->samples[i].sub_encry->sub_entry[n_idx].LenofEncryptData);\r
- }\r
- }\r
- }\r
-\r
- return TRUE;\r
-\r
-invalid_encryption:\r
- {\r
- GST_WARNING_OBJECT (piffdemux, "invalid sample encryption header");\r
- return FALSE;\r
- }\r
-}\r
-\r
-\r
-static gboolean\r
-piffdemux_parse_trun (GstPiffDemux * piffdemux, GstByteReader * trun,\r
- PiffDemuxStream * stream, guint32 d_sample_duration, guint32 d_sample_size,\r
- guint32 d_sample_flags, gint64 moof_offset, gint64 moof_length,\r
- gint64 * base_offset, gint64 * running_offset)\r
-{\r
- guint64 timestamp;\r
- gint32 data_offset = 0;\r
- guint32 flags = 0, first_flags = 0, samples_count = 0;\r
- gint i;\r
- guint8 *data;\r
- guint entry_size, dur_offset, size_offset, flags_offset = 0, ct_offset = 0;\r
- PiffDemuxSample *sample;\r
- gboolean ismv = FALSE;\r
- guint64 total_duration = 0;\r
-\r
- GST_LOG_OBJECT (piffdemux, "parsing trun stream ; "\r
- "default dur %d, size %d, flags 0x%x, base offset %" G_GINT64_FORMAT,\r
- d_sample_duration, d_sample_size, d_sample_flags,\r
- *base_offset);\r
-\r
- //Resetting the samples\r
- stream->n_samples = 0;\r
-\r
- if (!gst_byte_reader_skip (trun, 1) ||\r
- !gst_byte_reader_get_uint24_be (trun, &flags))\r
- goto fail;\r
-\r
- if (!gst_byte_reader_get_uint32_be (trun, &samples_count))\r
- goto fail;\r
-\r
- if (flags & TR_DATA_OFFSET) {\r
- /* note this is really signed */\r
- if (!gst_byte_reader_get_int32_be (trun, &data_offset))\r
- goto fail;\r
- GST_LOG_OBJECT (piffdemux, "trun data offset %d", data_offset);\r
- /* default base offset = first byte of moof */\r
- if (*base_offset == -1) {\r
- GST_LOG_OBJECT (piffdemux, "base_offset at moof and moof_offset = %"G_GINT64_FORMAT, moof_offset);\r
- *base_offset = moof_offset;\r
- }\r
- *running_offset = *base_offset + data_offset;\r
- } else {\r
- /* if no offset at all, that would mean data starts at moof start,\r
- * which is a bit wrong and is ismv crappy way, so compensate\r
- * assuming data is in mdat following moof */\r
- if (*base_offset == -1) {\r
- *base_offset = moof_offset + moof_length + 8;\r
- GST_LOG_OBJECT (piffdemux, "base_offset assumed in mdat after moof");\r
- ismv = TRUE;\r
- }\r
- if (*running_offset == -1)\r
- *running_offset = *base_offset;\r
- }\r
-\r
- GST_LOG_OBJECT (piffdemux, "running offset now %" G_GINT64_FORMAT,\r
- *running_offset);\r
- GST_LOG_OBJECT (piffdemux, "trun offset %d, flags 0x%x, entries %d",\r
- data_offset, flags, samples_count);\r
-\r
- if (flags & TR_FIRST_SAMPLE_FLAGS) {\r
- if (G_UNLIKELY (flags & TR_SAMPLE_FLAGS)) {\r
- GST_DEBUG_OBJECT (piffdemux,\r
- "invalid flags; SAMPLE and FIRST_SAMPLE present, discarding latter");\r
- flags ^= TR_FIRST_SAMPLE_FLAGS;\r
- } else {\r
- if (!gst_byte_reader_get_uint32_be (trun, &first_flags))\r
- goto fail;\r
- GST_LOG_OBJECT (piffdemux, "first flags: 0x%x", first_flags);\r
- }\r
- }\r
-\r
- /* FIXME ? spec says other bits should also be checked to determine\r
- * entry size (and prefix size for that matter) */\r
- entry_size = 0;\r
- dur_offset = size_offset = 0;\r
- if (flags & TR_SAMPLE_DURATION) {\r
- GST_LOG_OBJECT (piffdemux, "entry duration present");\r
- dur_offset = entry_size;\r
- entry_size += 4;\r
- }\r
- if (flags & TR_SAMPLE_SIZE) {\r
- GST_LOG_OBJECT (piffdemux, "entry size present");\r
- size_offset = entry_size;\r
- entry_size += 4;\r
- }\r
- if (flags & TR_SAMPLE_FLAGS) {\r
- GST_LOG_OBJECT (piffdemux, "entry flags present");\r
- flags_offset = entry_size;\r
- entry_size += 4;\r
- }\r
- if (flags & TR_COMPOSITION_TIME_OFFSETS) {\r
- GST_LOG_OBJECT (piffdemux, "entry ct offset present");\r
- ct_offset = entry_size;\r
- entry_size += 4;\r
- }\r
-\r
- if (!piff_atom_parser_has_chunks (trun, samples_count, entry_size))\r
- goto fail;\r
- data = (guint8 *) gst_byte_reader_peek_data_unchecked (trun);\r
-\r
- if (stream->n_samples >=\r
- PIFFDEMUX_MAX_SAMPLE_INDEX_SIZE / sizeof (PiffDemuxSample))\r
- goto index_too_big;\r
-\r
- GST_DEBUG_OBJECT (piffdemux, "allocating n_samples %u * %u (%.2f MB)",\r
- stream->n_samples, (guint) sizeof (PiffDemuxSample),\r
- stream->n_samples * sizeof (PiffDemuxSample) / (1024.0 * 1024.0));\r
-\r
- /* create a new array of samples if it's the first sample parsed */\r
- if (stream->n_samples == 0)\r
- stream->samples = g_try_new0 (PiffDemuxSample, samples_count);\r
- /* or try to reallocate it with space enough to insert the new samples */\r
- else\r
- stream->samples = g_try_renew (PiffDemuxSample, stream->samples,\r
- stream->n_samples + samples_count);\r
- if (stream->samples == NULL)\r
- goto out_of_memory;\r
-\r
- if (G_UNLIKELY (stream->n_samples == 0)) {\r
- /* the timestamp of the first sample is also provided by the tfra entry\r
- * but we shouldn't rely on it as it is at the end of files */\r
- timestamp = 0;\r
- } else {\r
- /* subsequent fragments extend stream */\r
- timestamp =\r
- stream->samples[stream->n_samples - 1].timestamp +\r
- stream->samples[stream->n_samples - 1].duration;\r
- }\r
- sample = stream->samples + stream->n_samples;\r
- for (i = 0; i < samples_count; i++) {\r
- guint32 dur, size, sflags, ct;\r
-\r
- /* first read sample data */\r
- if (flags & TR_SAMPLE_DURATION) {\r
- dur = PIFF_UINT32 (data + dur_offset);\r
- } else {\r
- dur = d_sample_duration;\r
- }\r
- if (flags & TR_SAMPLE_SIZE) {\r
- size = PIFF_UINT32 (data + size_offset);\r
- } else {\r
- size = d_sample_size;\r
- }\r
-\r
- GST_DEBUG_OBJECT(piffdemux,"Size of sample %d is %d", i, size);\r
-\r
- if (flags & TR_FIRST_SAMPLE_FLAGS) {\r
- if (i == 0) {\r
- sflags = first_flags;\r
- } else {\r
- sflags = d_sample_flags;\r
- }\r
- } else if (flags & TR_SAMPLE_FLAGS) {\r
- sflags = PIFF_UINT32 (data + flags_offset);\r
- } else {\r
- sflags = d_sample_flags;\r
- }\r
- if (flags & TR_COMPOSITION_TIME_OFFSETS) {\r
- ct = PIFF_UINT32 (data + ct_offset);\r
- } else {\r
- ct = 0;\r
- }\r
- data += entry_size;\r
-\r
- /* fill the sample information */\r
- sample->offset = *running_offset;\r
- sample->pts_offset = ct;\r
- sample->size = size;\r
- sample->timestamp = timestamp;\r
- sample->duration = dur;\r
- /* sample-is-difference-sample */\r
- /* ismv seems to use 0x40 for keyframe, 0xc0 for non-keyframe,\r
- * now idea how it relates to bitfield other than massive LE/BE confusion */\r
- sample->keyframe = ismv ? ((sflags & 0xff) == 0x40) : !(sflags & 0x10000);\r
- sample->iv = NULL;\r
- sample->sub_encry = NULL;\r
-\r
- stream->samples[i] = *sample;\r
-\r
- *running_offset += size;\r
- timestamp += dur;\r
- sample++;\r
-\r
- /* calculate total duration of the present fragment */\r
- total_duration += gst_util_uint64_scale (dur, GST_SECOND, stream->timescale);\r
- }\r
-\r
- stream->sample_index = 0;\r
-\r
- stream->n_samples += samples_count;\r
-\r
- /* calculate avg fps based on avg frame duration */\r
- stream->avg_dur = total_duration/samples_count;\r
- g_print ("total dur = %"GST_TIME_FORMAT", avg_dur = %"GST_TIME_FORMAT"count = %d\n",\r
- GST_TIME_ARGS(total_duration), GST_TIME_ARGS(stream->avg_dur), samples_count);\r
-\r
- return TRUE;\r
-\r
-fail:\r
- {\r
- GST_WARNING_OBJECT (piffdemux, "failed to parse trun");\r
- return FALSE;\r
- }\r
-out_of_memory:\r
- {\r
- GST_WARNING_OBJECT (piffdemux, "failed to allocate %d samples",\r
- stream->n_samples);\r
- return FALSE;\r
- }\r
-index_too_big:\r
- {\r
- GST_WARNING_OBJECT (piffdemux, "not allocating index of %d samples, would "\r
- "be larger than %uMB (broken file?)", stream->n_samples,\r
- PIFFDEMUX_MAX_SAMPLE_INDEX_SIZE >> 20);\r
- return FALSE;\r
- }\r
-}\r
-\r
-static gboolean\r
-piffdemux_parse_mfhd (GstPiffDemux * piffdemux, GstByteReader * mfhd)\r
-{\r
- guint32 seq_num = 0;\r
-\r
- if (!gst_byte_reader_skip (mfhd, 4))\r
- goto invalid_mfhd;\r
-\r
- if (!gst_byte_reader_get_uint32_be (mfhd, &seq_num))\r
- goto invalid_mfhd;\r
-\r
- GST_DEBUG_OBJECT (piffdemux, "sequence number present in mfhd = %d", seq_num);\r
-\r
- return TRUE;\r
-\r
-invalid_mfhd:\r
- {\r
- GST_WARNING_OBJECT (piffdemux, "invalid movie fragment header");\r
- return FALSE;\r
- }\r
-}\r
-\r
-\r
-static gboolean\r
-piffdemux_parse_tfhd (GstPiffDemux * piffdemux, GstByteReader * tfhd,\r
- guint32 * default_sample_duration,\r
- guint32 * default_sample_size, guint32 * default_sample_flags,\r
- gint64 * base_offset)\r
-{\r
- guint32 flags = 0;\r
- guint32 track_id = 0;\r
-\r
- if (!gst_byte_reader_skip (tfhd, 1) ||\r
- !gst_byte_reader_get_uint24_be (tfhd, &flags))\r
- goto invalid_track;\r
-\r
- if (!gst_byte_reader_get_uint32_be (tfhd, &track_id))\r
- goto invalid_track;\r
-\r
- GST_DEBUG_OBJECT (piffdemux, "trackID = %d", track_id);\r
-\r
- if (flags & TF_BASE_DATA_OFFSET) {\r
- if (!gst_byte_reader_get_uint64_be (tfhd, (guint64 *) base_offset))\r
- goto invalid_track;\r
- GST_DEBUG ("BaseData Offset = %"G_GUINT64_FORMAT, base_offset);\r
- }\r
-\r
- /* FIXME: Handle TF_SAMPLE_DESCRIPTION_INDEX properly */\r
- if (flags & TF_SAMPLE_DESCRIPTION_INDEX)\r
- if (!gst_byte_reader_skip (tfhd, 4))\r
- goto invalid_track;\r
-\r
- if (flags & TF_DEFAULT_SAMPLE_DURATION)\r
- if (!gst_byte_reader_get_uint32_be (tfhd, default_sample_duration))\r
- goto invalid_track;\r
-\r
- if (flags & TF_DEFAULT_SAMPLE_SIZE)\r
- if (!gst_byte_reader_get_uint32_be (tfhd, default_sample_size))\r
- goto invalid_track;\r
-\r
- if (flags & TF_DEFAULT_SAMPLE_FLAGS)\r
- if (!gst_byte_reader_get_uint32_be (tfhd, default_sample_flags))\r
- goto invalid_track;\r
-\r
- return TRUE;\r
-\r
-invalid_track:\r
- {\r
- GST_WARNING_OBJECT (piffdemux, "invalid track fragment header");\r
- return FALSE;\r
- }\r
-}\r
-\r
-static gboolean\r
-piffdemux_parse_tfxd (GstPiffDemux * piffdemux, PiffDemuxStream *stream,GstByteReader * tfxd)\r
-{\r
- guint8 version = 0;\r
-\r
- // TODO: In my opinion, tfxd will be mainly useful when lookahead count = 0. In this case, based on this duration, next fragment timstamp can be calculted.. Need to test this using our server\r
-\r
- if (!gst_byte_reader_get_uint8 (tfxd, &version))\r
- goto invalid_tfxd;\r
-\r
- if (!gst_byte_reader_skip (tfxd, 3))\r
- goto invalid_tfxd;\r
-\r
- if (!piffdemux->lookahead_cnt) {\r
- piffdemux->param = (piff_live_param_t *)malloc (sizeof (piff_live_param_t));\r
- if (NULL == piffdemux->param) {\r
- GST_ERROR_OBJECT (piffdemux, "Memory not available...\n");\r
- return FALSE;\r
- }\r
- piffdemux->param->count = 1;\r
- piffdemux->param->long_info = NULL;\r
- piffdemux->param->info = NULL;\r
- piffdemux->param->is_eos = FALSE;\r
-\r
- // TODO: presentation will be ended based on timeout in souphttpsrc in lookaheadcnt = 0 case\r
- }\r
-\r
- if (version == 1) {\r
- guint64 duration = 0;\r
- guint64 timestamp = 0;\r
-\r
- GST_LOG_OBJECT (piffdemux, "Time and Duration are in 64-bit format...");\r
- if (!gst_byte_reader_get_uint64_be (tfxd, ×tamp))\r
- goto invalid_tfxd;\r
- if (!gst_byte_reader_get_uint64_be (tfxd, &duration))\r
- goto invalid_tfxd;\r
-\r
- GST_DEBUG_OBJECT (piffdemux, "tfxd : absolute timestamp = %"G_GUINT64_FORMAT" and duration of fragment = %"G_GUINT64_FORMAT,\r
- timestamp, duration);\r
-\r
- if (!piffdemux->lookahead_cnt) {\r
- piffdemux->param->long_info = (piff_fragment_longtime_info *)malloc (piffdemux->param->count * sizeof (piff_fragment_longtime_info));\r
- if (NULL == piffdemux->param->long_info) {\r
- GST_ERROR_OBJECT (piffdemux, "Memory not available...\n");\r
- return FALSE;\r
- }\r
-\r
- /* Calculate next fragment's timestamp using current fragment's timestamp + duration */\r
- piffdemux->param->long_info->duration = GST_CLOCK_TIME_NONE;\r
- piffdemux->param->long_info->ts = timestamp +duration;\r
- }\r
- } else if (version == 0) {\r
- guint32 duration = 0;\r
- guint32 timestamp = 0;\r
- GST_LOG_OBJECT (piffdemux, "Time and Duration are in 32-bit format...");\r
-\r
- if (!gst_byte_reader_get_uint32_be (tfxd, ×tamp))\r
- goto invalid_tfxd;\r
-\r
- if (!gst_byte_reader_get_uint32_be (tfxd, &duration))\r
- goto invalid_tfxd;\r
-\r
- GST_DEBUG_OBJECT (piffdemux, "tfxd : absolute timestamp = %"G_GUINT32_FORMAT" and duration of fragment = %"G_GUINT32_FORMAT,\r
- timestamp, duration);\r
-\r
- if (!piffdemux->lookahead_cnt) {\r
- piffdemux->param->info = (piff_fragment_time_info *)malloc (piffdemux->param->count * sizeof (piff_fragment_time_info));\r
- if (NULL == piffdemux->param->info) {\r
- GST_ERROR_OBJECT (piffdemux, "Memory not available...\n");\r
- return FALSE;\r
- }\r
- /* Calculate next fragment's timestamp using current fragment's timestamp + duration */\r
- piffdemux->param->info->duration = GST_CLOCK_TIME_NONE;\r
- piffdemux->param->info->ts = timestamp +duration;\r
- }\r
- } else {\r
- GST_ERROR_OBJECT (piffdemux, "Invalid Version in tfxd...");\r
- return FALSE;\r
- }\r
-\r
- if (!piffdemux->lookahead_cnt) {\r
- GST_DEBUG_OBJECT (piffdemux, "Emitting live-param signal...");\r
- g_signal_emit (piffdemux, gst_piffdemux_signals[SIGNAL_LIVE_PARAM], 0, piffdemux->param);\r
- }\r
-\r
- return TRUE;\r
-\r
-invalid_tfxd:\r
- GST_ERROR ("Invalid TFXD atom...");\r
- return FALSE;\r
-}\r
-\r
-\r
-static gboolean\r
-piffdemux_parse_tfrf (GstPiffDemux * piffdemux, PiffDemuxStream *stream,GstByteReader * tfrf)\r
-{\r
- guint8 version = 0;\r
- guint8 frag_cnt = 0;\r
- guint8 i = 0;\r
-\r
- /* Getting version info */\r
- if (!gst_byte_reader_get_uint8 (tfrf, &version))\r
- goto invalid_tfrf;\r
-\r
- /* skipping reserved flags */\r
- if (!gst_byte_reader_skip (tfrf, 3))\r
- goto invalid_tfrf;\r
-\r
- if (!gst_byte_reader_get_uint8 (tfrf, &frag_cnt))\r
- goto invalid_tfrf;\r
-\r
- GST_INFO_OBJECT (piffdemux, "Subsequent fragments info count = %d", frag_cnt);\r
-\r
- piffdemux->param = (piff_live_param_t *)malloc(sizeof (piff_live_param_t));\r
- if (NULL == piffdemux->param) {\r
- GST_ERROR_OBJECT (piffdemux, "Memory not available...\n");\r
- return FALSE;\r
- }\r
-\r
- piffdemux->param->count = frag_cnt;\r
- piffdemux->param->long_info = NULL;\r
- piffdemux->param->info = NULL;\r
- piffdemux->param->is_eos = FALSE;\r
-\r
- // TODO: Duration and timestamp values need to be posted to msl using g_signal_emit\r
-\r
- if (version == 1) {\r
- guint64 duration = 0;\r
- guint64 timestamp = 0;\r
- GST_LOG_OBJECT (piffdemux, "Time and Duration are in 64-bit format...");\r
-\r
- piffdemux->param->long_info = (piff_fragment_longtime_info *)malloc (piffdemux->param->count * sizeof (piff_fragment_longtime_info));\r
- if (NULL == piffdemux->param->long_info) {\r
- GST_ERROR_OBJECT (piffdemux, "Memory not available...\n");\r
- return FALSE;\r
- }\r
-\r
- for (i = 0; i < frag_cnt; i++) {\r
- if (!gst_byte_reader_get_uint64_be (tfrf, ×tamp))\r
- goto invalid_tfrf;\r
- if (!gst_byte_reader_get_uint64_be (tfrf, &duration))\r
- goto invalid_tfrf;\r
- GST_DEBUG_OBJECT (piffdemux, "tfrf long: absolute timestamp = %"G_GUINT64_FORMAT" and duration of fragment = %"G_GUINT64_FORMAT"\n",\r
- timestamp, duration);\r
- (piffdemux->param->long_info[i]).ts = timestamp;\r
- (piffdemux->param->long_info[i]).duration = duration;\r
- }\r
- } else if (version == 0) {\r
- guint32 duration = 0;\r
- guint32 timestamp = 0;\r
- GST_LOG_OBJECT (piffdemux, "Time and Duration are in 32-bit format...");\r
-\r
- piffdemux->param->info = (piff_fragment_time_info *)malloc (piffdemux->param->count * sizeof (piff_fragment_time_info));\r
- if (NULL == piffdemux->param->info) {\r
- GST_ERROR ("Memory not available...\n");\r
- return FALSE;\r
- }\r
-\r
- for (i = 0; i < frag_cnt; i++) {\r
- if (!gst_byte_reader_get_uint32_be (tfrf, ×tamp))\r
- goto invalid_tfrf;\r
- if (!gst_byte_reader_get_uint32_be (tfrf, &duration))\r
- goto invalid_tfrf;\r
-\r
- GST_DEBUG_OBJECT (piffdemux, "tfrf int: absolute timestamp = %"G_GUINT32_FORMAT" and duration of fragment = %"G_GUINT32_FORMAT,\r
- timestamp, duration);\r
- (piffdemux->param->info[i]).ts = timestamp;\r
- (piffdemux->param->info[i]).duration = duration;\r
- }\r
- } else {\r
- GST_ERROR_OBJECT (piffdemux, "Invalid Version in tfrf...");\r
- return FALSE;\r
- }\r
-\r
- g_print ("Signalling from TFRF box..\n");\r
- g_signal_emit (piffdemux, gst_piffdemux_signals[SIGNAL_LIVE_PARAM], 0, piffdemux->param);\r
-\r
- return TRUE;\r
-\r
-invalid_tfrf:\r
- GST_ERROR_OBJECT (piffdemux, "Invalid TFRF atom...");\r
- return FALSE;\r
-}\r
-\r
-\r
-static gboolean\r
-piffdemux_parse_moof (GstPiffDemux * piffdemux, const guint8 * buffer, guint length,\r
- guint64 moof_offset, PiffDemuxStream * stream)\r
-{\r
- GNode *moof_node, *mfhd_node, *traf_node, *tfhd_node, *trun_node, *uuid_node;\r
- GstByteReader mfhd_data, trun_data, tfhd_data, uuid_data;\r
- guint32 ds_size = 0, ds_duration = 0, ds_flags = 0;\r
- gint64 base_offset, running_offset;\r
- gint64 uuid_offset = 0;\r
- gboolean found_tfxd = FALSE;\r
- gboolean found_tfrf = FALSE;\r
-\r
- /* NOTE @stream ignored */\r
-\r
- moof_node = g_node_new ((guint8 *) buffer);\r
- piffdemux_parse_node (piffdemux, moof_node, buffer, length);\r
- //piffdemux_node_dump (piffdemux, moof_node);\r
-\r
- /* unknown base_offset to start with */\r
- base_offset = running_offset = -1;\r
-\r
- mfhd_node = piffdemux_tree_get_child_by_type_full (moof_node, FOURCC_mfhd, &mfhd_data);\r
- if (!mfhd_node)\r
- goto missing_mfhd;\r
-\r
- if (!piffdemux_parse_mfhd (piffdemux, &mfhd_data))\r
- goto missing_mfhd;\r
-\r
- traf_node = piffdemux_tree_get_child_by_type (moof_node, FOURCC_traf);\r
- while (traf_node) {\r
- /* Fragment Header node */\r
- tfhd_node =\r
- piffdemux_tree_get_child_by_type_full (traf_node, FOURCC_tfhd,\r
- &tfhd_data);\r
- if (!tfhd_node)\r
- goto missing_tfhd;\r
- if (!piffdemux_parse_tfhd (piffdemux, &tfhd_data, &ds_duration,\r
- &ds_size, &ds_flags, &base_offset))\r
- goto missing_tfhd;\r
-\r
- if (G_UNLIKELY (base_offset < -1))\r
- goto lost_offset;\r
-\r
- /* Track Run node */\r
- trun_node =\r
- piffdemux_tree_get_child_by_type_full (traf_node, FOURCC_trun,\r
- &trun_data);\r
- while (trun_node) {\r
- piffdemux_parse_trun (piffdemux, &trun_data, stream,\r
- ds_duration, ds_size, ds_flags, moof_offset, length, &base_offset,\r
- &running_offset);\r
- /* iterate all siblings */\r
- trun_node = piffdemux_tree_get_sibling_by_type_full (trun_node, FOURCC_trun,\r
- &trun_data);\r
- }\r
-\r
- uuid_node = piffdemux_tree_get_child_by_type (traf_node, FOURCC_uuid);\r
- while (uuid_node) {\r
- uuid_type_t uuid_type;\r
- guint8 *buffer = (guint8 *) uuid_node->data;\r
-\r
- gst_byte_reader_init (&uuid_data, buffer, PIFF_UINT32 (buffer));\r
-\r
- uuid_type = piffdemux_get_uuid_type (piffdemux, &uuid_data, &uuid_offset);\r
-\r
- if ((UUID_TFXD == uuid_type) && piffdemux->is_live) {\r
- // TODO: Dont know, why we should not consider tfxd offset...if we use tfxd offset also, not working.. PIFF doc does not say anything :(\r
- found_tfxd = TRUE;\r
- if (!piffdemux_parse_tfxd (piffdemux, stream, &uuid_data))\r
- goto fail;\r
- } else if ((UUID_TFRF == uuid_type) && piffdemux->is_live && piffdemux->lookahead_cnt) {\r
- found_tfrf = TRUE;\r
- if (!piffdemux_parse_tfrf (piffdemux, stream, &uuid_data))\r
- goto fail;\r
- piffdemux_update_sample_offset (piffdemux, stream, uuid_offset);\r
- running_offset += uuid_offset;\r
- } else if (UUID_SAMPLE_ENCRYPT == uuid_type) {\r
- if (!piffdemux_parse_sample_encryption (piffdemux, &uuid_data, stream))\r
- goto fail;\r
- } else {\r
- GST_WARNING_OBJECT (piffdemux, "Ignoring Wrong UUID...");\r
- }\r
-\r
- /* iterate all siblings */\r
- uuid_node = piffdemux_tree_get_sibling_by_type (uuid_node, FOURCC_uuid);\r
- }\r
-\r
- if (piffdemux->is_live) {\r
- if (!found_tfxd) {\r
- GST_ERROR_OBJECT (piffdemux, "TFXD box is not present for live stream");\r
- goto fail;\r
- }\r
-\r
- if (!found_tfrf && piffdemux->lookahead_cnt) {\r
- /* when lookahead count is non-zero in manifest & if tfrf box is not present., means EOS */\r
- GST_INFO_OBJECT (piffdemux, "Reached Endof Live presentation..");\r
-\r
- piffdemux->param = (piff_live_param_t *)malloc (sizeof (piff_live_param_t));\r
- if (NULL == piffdemux->param) {\r
- GST_ERROR_OBJECT (piffdemux, "Memory not available...\n");\r
- goto fail;\r
- }\r
- piffdemux->param->count = 0;\r
- piffdemux->param->long_info = NULL;\r
- piffdemux->param->info = NULL;\r
- piffdemux->param->is_eos = TRUE; /* marking EOS */\r
- g_signal_emit (piffdemux, gst_piffdemux_signals[SIGNAL_LIVE_PARAM], 0, piffdemux->param);\r
- }\r
- }\r
-\r
- /* if no new base_offset provided for next traf,\r
- * base is end of current traf */\r
- base_offset = running_offset;\r
- running_offset = -1;\r
-\r
- /* iterate all siblings */\r
- traf_node = piffdemux_tree_get_sibling_by_type (traf_node, FOURCC_traf);\r
- }\r
- g_node_destroy (moof_node);\r
- return TRUE;\r
-\r
-missing_mfhd:\r
- {\r
- GST_DEBUG_OBJECT (piffdemux, "missing mfhd box");\r
- goto fail;\r
- }\r
-\r
-missing_tfhd:\r
- {\r
- GST_DEBUG_OBJECT (piffdemux, "missing tfhd box");\r
- goto fail;\r
- }\r
-lost_offset:\r
- {\r
- GST_DEBUG_OBJECT (piffdemux, "lost offset");\r
- goto fail;\r
- }\r
-fail:\r
- {\r
- g_node_destroy (moof_node);\r
-\r
- GST_ELEMENT_ERROR (piffdemux, STREAM, DEMUX,\r
- ("This file is corrupt and cannot be played."), (NULL));\r
-\r
- return FALSE;\r
- }\r
-}\r
-\r
-\r
-/* activate the given segment number @seg_idx of @stream at time @offset.\r
- * @offset is an absolute global position over all the segments.\r
- *\r
- * This will push out a NEWSEGMENT event with the right values and\r
- * position the stream index to the first decodable sample before\r
- * @offset.\r
- */\r
-static gboolean\r
-gst_piffdemux_activate_segment (GstPiffDemux * piffdemux, PiffDemuxStream * stream,\r
- guint32 seg_idx, guint64 offset)\r
-{\r
- GstEvent *event;\r
- PiffDemuxSegment *segment;\r
- guint64 seg_time;\r
- guint64 start, stop, time;\r
- gdouble rate;\r
-\r
- GST_LOG_OBJECT (piffdemux, "activate segment %d, offset %" G_GUINT64_FORMAT,\r
- seg_idx, offset);\r
-\r
- /* update the current segment */\r
- stream->segment_index = seg_idx;\r
-\r
- /* get the segment */\r
- segment = &stream->segments[seg_idx];\r
-\r
- if (G_UNLIKELY (offset < segment->time)) {\r
- GST_WARNING_OBJECT (piffdemux, "offset < segment->time %" G_GUINT64_FORMAT,\r
- segment->time);\r
- return FALSE;\r
- }\r
-\r
- /* segment lies beyond total indicated duration */\r
- if (G_UNLIKELY (piffdemux->segment.duration != -1 &&\r
- segment->time > piffdemux->segment.duration)) {\r
- GST_WARNING_OBJECT (piffdemux, "file duration %" G_GINT64_FORMAT\r
- " < segment->time %" G_GUINT64_FORMAT, piffdemux->segment.duration,\r
- segment->time);\r
- return FALSE;\r
- }\r
-\r
- /* get time in this segment */\r
- seg_time = offset - segment->time;\r
-\r
- GST_LOG_OBJECT (piffdemux, "seg_time %" GST_TIME_FORMAT,\r
- GST_TIME_ARGS (seg_time));\r
-\r
- if (G_UNLIKELY (seg_time > segment->duration)) {\r
- GST_LOG_OBJECT (piffdemux, "seg_time > segment->duration %" GST_TIME_FORMAT,\r
- GST_TIME_ARGS (segment->duration));\r
- return FALSE;\r
- }\r
-\r
- /* piffdemux->segment.stop is in outside-time-realm, whereas\r
- * segment->media_stop is in track-time-realm.\r
- *\r
- * In order to compare the two, we need to bring segment.stop\r
- * into the track-time-realm */\r
-\r
- stop = piffdemux->segment.stop;\r
- if (stop == -1)\r
- stop = piffdemux->segment.duration;\r
- if (stop == -1)\r
- stop = segment->media_stop;\r
- else\r
- stop =\r
- MIN (segment->media_stop, stop - segment->time + segment->media_start);\r
-\r
- if (piffdemux->segment.rate >= 0) {\r
- start = MIN (segment->media_start + seg_time, stop);\r
- time = offset;\r
- } else {\r
- if (segment->media_start >= piffdemux->segment.start) {\r
- start = segment->media_start;\r
- time = segment->time;\r
- } else {\r
- start = piffdemux->segment.start;\r
- time = segment->time + (piffdemux->segment.start - segment->media_start);\r
- }\r
-\r
- start = MAX (segment->media_start, piffdemux->segment.start);\r
- stop = MIN (segment->media_start + seg_time, stop);\r
- }\r
-\r
- GST_DEBUG_OBJECT (piffdemux, "newsegment %d from %" GST_TIME_FORMAT\r
- " to %" GST_TIME_FORMAT ", time %" GST_TIME_FORMAT, seg_idx,\r
- GST_TIME_ARGS (start), GST_TIME_ARGS (stop), GST_TIME_ARGS (time));\r
-\r
- /* combine global rate with that of the segment */\r
- rate = segment->rate * piffdemux->segment.rate;\r
-\r
- /* update the segment values used for clipping */\r
- gst_segment_init (&stream->segment, GST_FORMAT_TIME);\r
- gst_segment_set_newsegment (&stream->segment, FALSE, rate, GST_FORMAT_TIME,\r
- start, stop, time);\r
-\r
- /* now prepare and send the segment */\r
- event = gst_event_new_new_segment (FALSE, rate, GST_FORMAT_TIME,\r
- start, stop, time);\r
- gst_pad_push_event (piffdemux->srcpad, event);\r
- /* assume we can send more data now */\r
- stream->last_ret = GST_FLOW_OK;\r
- /* clear to send tags on this pad now */\r
- gst_piffdemux_push_tags (piffdemux, stream);\r
-\r
- return TRUE;\r
-}\r
-\r
-\r
-/* prepare to get the current sample of @stream, getting essential values.\r
- *\r
- * This function will also prepare and send the segment when needed.\r
- *\r
- * Return FALSE if the stream is EOS.\r
- */\r
-static gboolean\r
-gst_piffdemux_prepare_current_sample (GstPiffDemux * piffdemux,\r
- PiffDemuxStream * stream, guint64 * offset, guint * size, guint64 * timestamp,\r
- guint64 * duration, gboolean * keyframe)\r
-{\r
- PiffDemuxSample *sample;\r
- guint64 time_position;\r
- guint32 seg_idx;\r
-\r
- g_return_val_if_fail (stream != NULL, FALSE);\r
-\r
- time_position = stream->time_position;\r
- if (G_UNLIKELY (time_position == -1))\r
- goto eos;\r
-\r
- seg_idx = stream->segment_index;\r
- if (G_UNLIKELY (seg_idx == -1)) {\r
- /* find segment corresponding to time_position if we are looking\r
- * for a segment. */\r
- seg_idx = gst_piffdemux_find_segment (piffdemux, stream, time_position);\r
-\r
- /* nothing found, we're really eos */\r
- if (seg_idx == -1)\r
- goto eos;\r
- }\r
-\r
- /* different segment, activate it, sample_index will be set. */\r
- if (G_UNLIKELY (stream->segment_index != seg_idx))\r
- gst_piffdemux_activate_segment (piffdemux, stream, seg_idx, time_position);\r
-\r
- GST_LOG_OBJECT (piffdemux, "segment active, index = %u of %u",\r
- stream->sample_index, stream->n_samples);\r
-\r
- if (G_UNLIKELY (stream->sample_index >= stream->n_samples))\r
- goto eos;\r
-\r
-\r
- /* now get the info for the sample we're at */\r
- sample = &stream->samples[stream->sample_index];\r
-\r
- *timestamp = PIFFSAMPLE_PTS (stream, sample);\r
- *offset = sample->offset;\r
- *size = sample->size;\r
- *duration = PIFFSAMPLE_DUR_PTS (stream, sample, *timestamp);\r
- *keyframe = PIFFSAMPLE_KEYFRAME (stream, sample);\r
-\r
- return TRUE;\r
-\r
- /* special cases */\r
-eos:\r
- {\r
- stream->time_position = -1;\r
- return FALSE;\r
- }\r
-}\r
-\r
-/* the input buffer metadata must be writable,\r
- * but time/duration etc not yet set and need not be preserved */\r
-static GstBuffer *\r
-gst_piffdemux_process_buffer (GstPiffDemux * piffdemux, PiffDemuxStream * stream,\r
- GstBuffer * buf)\r
-{\r
- guint8 *data;\r
- guint size, nsize = 0;\r
- gchar *str;\r
-\r
- data = GST_BUFFER_DATA (buf);\r
- size = GST_BUFFER_SIZE (buf);\r
-\r
- if (G_UNLIKELY (stream->subtype != FOURCC_text)) {\r
- return buf;\r
- }\r
-\r
- if (G_LIKELY (size >= 2)) {\r
- nsize = GST_READ_UINT16_BE (data);\r
- nsize = MIN (nsize, size - 2);\r
- }\r
-\r
- GST_LOG_OBJECT (piffdemux, "3GPP timed text subtitle: %d/%d", nsize, size);\r
-\r
- /* takes care of UTF-8 validation or UTF-16 recognition,\r
- * no other encoding expected */\r
- str = gst_tag_freeform_string_to_utf8 ((gchar *) data + 2, nsize, NULL);\r
- if (str) {\r
- gst_buffer_unref (buf);\r
- buf = gst_buffer_new ();\r
- GST_BUFFER_DATA (buf) = GST_BUFFER_MALLOCDATA (buf) = (guint8 *) str;\r
- GST_BUFFER_SIZE (buf) = strlen (str);\r
- } else {\r
- /* may be 0-size subtitle, which is also sent to keep pipeline going */\r
- GST_BUFFER_DATA (buf) = data + 2;\r
- GST_BUFFER_SIZE (buf) = nsize;\r
- }\r
-\r
- /* FIXME ? convert optional subsequent style info to markup */\r
-\r
- return buf;\r
-}\r
-\r
-/* Sets a buffer's attributes properly and pushes it downstream.\r
- * Also checks for additional actions and custom processing that may\r
- * need to be done first.\r
- */\r
-static gboolean\r
-gst_piffdemux_decorate_and_push_buffer (GstPiffDemux * piffdemux,\r
- PiffDemuxStream * stream, GstBuffer * buf,\r
- guint64 timestamp, guint64 duration, gboolean keyframe, guint64 position,\r
- guint64 byte_position)\r
-{\r
- GstFlowReturn ret = GST_FLOW_OK;\r
-\r
- if (!stream->caps) {\r
- GST_WARNING_OBJECT (piffdemux, "caps are empty...creat any caps");\r
- stream->caps = gst_caps_new_any();\r
- if (!stream->caps) {\r
- GST_ERROR_OBJECT (piffdemux, "failed to create caps...");\r
- ret = GST_FLOW_ERROR;\r
- goto exit;\r
- }\r
- }\r
-\r
- /* position reporting */\r
- if (piffdemux->segment.rate >= 0) {\r
- // TODO: Segment fault is coming here for Audio stream.. need to check\r
- gst_segment_set_last_stop (&piffdemux->segment, GST_FORMAT_TIME, position);\r
- //gst_piffdemux_sync_streams (piffdemux);\r
- }\r
-\r
- /* send out pending buffers */\r
- while (stream->buffers) {\r
- GstBuffer *buffer = (GstBuffer *) stream->buffers->data;\r
-\r
- if (G_UNLIKELY (stream->discont)) {\r
- GST_LOG_OBJECT (piffdemux, "marking discont buffer");\r
- GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DISCONT);\r
- stream->discont = FALSE;\r
- }\r
- gst_buffer_set_caps (buffer, stream->caps);\r
-\r
- gst_pad_push (piffdemux->srcpad, buffer);\r
-\r
- stream->buffers = g_slist_delete_link (stream->buffers, stream->buffers);\r
- }\r
-\r
- /* we're going to modify the metadata */\r
- buf = gst_buffer_make_metadata_writable (buf);\r
-\r
- /* for subtitle processing */\r
- if (G_UNLIKELY (stream->need_process))\r
- buf = gst_piffdemux_process_buffer (piffdemux, stream, buf);\r
-\r
- GST_BUFFER_TIMESTAMP (buf) = timestamp;\r
- GST_BUFFER_DURATION (buf) = duration;\r
- GST_BUFFER_OFFSET (buf) = -1;\r
- GST_BUFFER_OFFSET_END (buf) = -1;\r
-\r
- if (G_UNLIKELY (stream->padding)) {\r
- GST_BUFFER_DATA (buf) += stream->padding;\r
- GST_BUFFER_SIZE (buf) -= stream->padding;\r
- }\r
-\r
- if (G_UNLIKELY (buf == NULL))\r
- goto exit;\r
-\r
- if (G_UNLIKELY (stream->discont)) {\r
- GST_LOG_OBJECT (piffdemux, "marking discont buffer");\r
- GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);\r
- stream->discont = FALSE;\r
- }\r
-\r
- if (!keyframe)\r
- GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DELTA_UNIT);\r
-\r
- //g_print ("\n\npad caps : %s\n\n", gst_caps_to_string (gst_pad_get_caps (stream->pad)));\r
-\r
- //gst_buffer_set_caps (buf, stream->caps); // commenting to avoid caps by setting properties\r
-\r
-\r
- // TODO: need to see how resolution switch will work\r
- gst_buffer_set_caps (buf, stream->caps);\r
-\r
- GST_LOG_OBJECT (piffdemux,\r
- "Pushing buffer of size = %d with time %" GST_TIME_FORMAT ", duration %"\r
- GST_TIME_FORMAT, GST_BUFFER_SIZE(buf), GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)),\r
- GST_TIME_ARGS (GST_BUFFER_DURATION (buf)));\r
-\r
-#ifdef DEC_OUT_FRAME_DUMP\r
- {\r
- int written = 0;\r
- written = fwrite (GST_BUFFER_DATA (buf), sizeof (unsigned char), GST_BUFFER_SIZE (buf), piffdump);\r
- g_print ("PIFFDEMUX: written = %d\n", written);\r
- fflush (piffdump);\r
- }\r
-#endif\r
-\r
- ret = gst_pad_push (piffdemux->srcpad, buf);\r
-\r
-exit:\r
- return ret;\r
-}\r
-\r
-\r
-/*\r
- * next_entry_size\r
- *\r
- * Returns the size of the first entry at the current offset.\r
- * If -1, there are none (which means EOS or empty file).\r
- */\r
-static guint64\r
-next_entry_size (GstPiffDemux * demux)\r
-{\r
- PiffDemuxStream *stream = demux->stream;\r
- PiffDemuxSample *sample;\r
-\r
- GST_LOG_OBJECT (demux, "Finding entry at offset %" G_GUINT64_FORMAT,\r
- demux->offset);\r
-\r
- GST_DEBUG_OBJECT (demux, "demux->sample_index = %d", stream->sample_index);\r
-\r
- if (stream->sample_index == -1)\r
- stream->sample_index = 0;\r
-\r
- if (stream->sample_index >= stream->n_samples) {\r
- GST_LOG_OBJECT (demux, "stream %d samples exhausted n_samples = %d",\r
- stream->sample_index, stream->n_samples);\r
- return -1;\r
- }\r
-\r
- sample = &stream->samples[stream->sample_index];\r
-\r
- GST_LOG_OBJECT (demux,\r
- "Checking Stream %d (sample_index:%d / offset:%" G_GUINT64_FORMAT\r
- " / size:%" G_GUINT32_FORMAT ")", stream->sample_index, stream->sample_index,\r
- sample->offset, sample->size);\r
-\r
- GST_LOG_OBJECT (demux, "stream : demux->offset :%"G_GUINT64_FORMAT, demux->offset);\r
-\r
- stream = demux->stream;\r
- sample = &stream->samples[stream->sample_index];\r
-\r
- if (sample->offset >= demux->offset) {\r
- demux->todrop = sample->offset - demux->offset;\r
- return sample->size + demux->todrop;\r
- }\r
-\r
- GST_DEBUG_OBJECT (demux,\r
- "There wasn't any entry at offset %" G_GUINT64_FORMAT, demux->offset);\r
- return -1;\r
-}\r
-\r
-static void\r
-gst_piffdemux_post_progress (GstPiffDemux * demux, gint num, gint denom)\r
-{\r
- gint perc = (gint) ((gdouble) num * 100.0 / (gdouble) denom);\r
-\r
- gst_element_post_message (GST_ELEMENT_CAST (demux),\r
- gst_message_new_element (GST_OBJECT_CAST (demux),\r
- gst_structure_new ("progress", "percent", G_TYPE_INT, perc, NULL)));\r
-}\r
-\r
-static gboolean\r
-piffdemux_seek_offset (GstPiffDemux * demux, guint64 offset)\r
-{\r
- GstEvent *event;\r
- gboolean res = 0;\r
-\r
- GST_DEBUG_OBJECT (demux, "Seeking to %" G_GUINT64_FORMAT, offset);\r
-\r
- event =\r
- gst_event_new_seek (1.0, GST_FORMAT_BYTES,\r
- GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE, GST_SEEK_TYPE_SET, offset,\r
- GST_SEEK_TYPE_NONE, -1);\r
-\r
- res = gst_pad_push_event (demux->sinkpad, event);\r
-\r
- return res;\r
-}\r
-\r
-static GstFlowReturn\r
-gst_piffdemux_chain (GstPad * sinkpad, GstBuffer * inbuf)\r
-{\r
- GstPiffDemux *demux;\r
- GstFlowReturn ret = GST_FLOW_OK;\r
- demux = GST_PIFFDEMUX (gst_pad_get_parent (sinkpad));\r
-\r
- gst_adapter_push (demux->adapter, inbuf);\r
-\r
- /* we never really mean to buffer that much */\r
- if (demux->neededbytes == -1)\r
- goto eos;\r
-\r
- GST_DEBUG_OBJECT (demux, "pushing in inbuf %p, neededbytes:%u, available:%u",\r
- inbuf, demux->neededbytes, gst_adapter_available (demux->adapter));\r
-\r
- while (((gst_adapter_available (demux->adapter)) >= demux->neededbytes) &&\r
- (ret == GST_FLOW_OK)) {\r
-\r
- GST_DEBUG_OBJECT (demux,\r
- "state:%d , demux->neededbytes:%d, demux->offset:%" G_GUINT64_FORMAT,\r
- demux->state, demux->neededbytes, demux->offset);\r
-\r
- switch (demux->state) {\r
- case PIFFDEMUX_STATE_INITIAL:{\r
- const guint8 *data;\r
- guint32 fourcc;\r
- guint64 size;\r
-\r
- data = gst_adapter_peek (demux->adapter, demux->neededbytes);\r
-\r
- /* get fourcc/length, set neededbytes */\r
- extract_initial_length_and_fourcc ((guint8 *) data, demux->neededbytes,\r
- &size, &fourcc);\r
- GST_DEBUG_OBJECT (demux, "Peeking found [%" GST_FOURCC_FORMAT "] "\r
- "size: %" G_GUINT64_FORMAT, GST_FOURCC_ARGS (fourcc), size);\r
- if (size == 0) {\r
- GST_ELEMENT_ERROR (demux, STREAM, DEMUX,\r
- ("This file is invalid and cannot be played."),\r
- ("initial atom '%" GST_FOURCC_FORMAT "' has empty length",\r
- GST_FOURCC_ARGS (fourcc)));\r
-\r
- ret = GST_FLOW_ERROR;\r
- break;\r
- }\r
-\r
- if (fourcc == FOURCC_mdat) {\r
- if (demux->moof_rcvd) {\r
- /* we have the headers, start playback */\r
- demux->state = PIFFDEMUX_STATE_MOVIE;\r
- demux->neededbytes = next_entry_size (demux);\r
- demux->mdatleft = size;\r
-\r
- /* Only post, event on pads is done after newsegment */\r
- piffdemux_post_global_tags (demux);\r
- } else {\r
- GST_ERROR_OBJECT (demux, "mdata received before moof.. not handled");\r
- goto unknown_stream;\r
- }\r
- } else if (G_UNLIKELY (size > PIFFDEMUX_MAX_ATOM_SIZE)) {\r
- GST_ELEMENT_ERROR (demux, STREAM, DEMUX,\r
- ("This file is invalid and cannot be played."),\r
- ("atom %" GST_FOURCC_FORMAT " has bogus size %" G_GUINT64_FORMAT,\r
- GST_FOURCC_ARGS (fourcc), size));\r
- ret = GST_FLOW_ERROR;\r
- break;\r
- } else {\r
- demux->neededbytes = size;\r
- demux->state = PIFFDEMUX_STATE_HEADER;\r
- }\r
- break;\r
- }\r
- case PIFFDEMUX_STATE_HEADER:{\r
- const guint8 *data;\r
- guint32 fourcc;\r
-\r
- GST_DEBUG_OBJECT (demux, "In header");\r
-\r
- data = gst_adapter_peek (demux->adapter, demux->neededbytes);\r
-\r
- /* parse the header */\r
- extract_initial_length_and_fourcc (data, demux->neededbytes, NULL,\r
- &fourcc);\r
- if (fourcc == FOURCC_moof) {\r
- GST_DEBUG_OBJECT (demux, "Parsing [moof]");\r
- if (!piffdemux_parse_moof (demux, data, demux->neededbytes,\r
- demux->offset, demux->stream)) {\r
- ret = GST_FLOW_ERROR;\r
- goto done;\r
- }\r
- demux->moof_rcvd = TRUE;\r
- } else {\r
- GST_WARNING_OBJECT (demux,\r
- "Unknown fourcc while parsing header : %" GST_FOURCC_FORMAT,\r
- GST_FOURCC_ARGS (fourcc));\r
- /* Let's jump that one and go back to initial state */\r
- }\r
-\r
- if (demux->mdatbuffer) {\r
- /* the mdat was before the header */\r
- GST_DEBUG_OBJECT (demux, "We have mdatbuffer:%p",\r
- demux->mdatbuffer);\r
- gst_adapter_clear (demux->adapter);\r
- demux->mdatbuffer = NULL;\r
- demux->offset = demux->mdatoffset;\r
- demux->neededbytes = next_entry_size (demux);\r
- demux->state = PIFFDEMUX_STATE_MOVIE;\r
- demux->mdatleft = gst_adapter_available (demux->adapter);\r
-\r
- /* Only post, event on pads is done after newsegment */\r
- piffdemux_post_global_tags (demux);\r
- } else {\r
- GST_DEBUG_OBJECT (demux, "Carrying on normally");\r
- gst_adapter_flush (demux->adapter, demux->neededbytes);\r
- demux->offset += demux->neededbytes;\r
- demux->neededbytes = 16;\r
- demux->state = PIFFDEMUX_STATE_INITIAL;\r
- }\r
-\r
- break;\r
- }\r
- case PIFFDEMUX_STATE_BUFFER_MDAT:{\r
- GstBuffer *buf;\r
-\r
- GST_DEBUG_OBJECT (demux, "Got our buffer at offset %" G_GUINT64_FORMAT,\r
- demux->offset);\r
- buf = gst_adapter_take_buffer (demux->adapter, demux->neededbytes);\r
- GST_DEBUG_OBJECT (demux, "mdatbuffer starts with %" GST_FOURCC_FORMAT,\r
- GST_FOURCC_ARGS (PIFF_FOURCC (GST_BUFFER_DATA (buf) + 4)));\r
- if (demux->mdatbuffer)\r
- demux->mdatbuffer = gst_buffer_join (demux->mdatbuffer, buf);\r
- else\r
- demux->mdatbuffer = buf;\r
- demux->offset += demux->neededbytes;\r
- demux->neededbytes = 16;\r
- demux->state = PIFFDEMUX_STATE_INITIAL;\r
- gst_piffdemux_post_progress (demux, 1, 1);\r
-\r
- break;\r
- }\r
- case PIFFDEMUX_STATE_MOVIE:{\r
- GstBuffer *outbuf;\r
- PiffDemuxStream *stream = demux->stream;\r
- PiffDemuxSample *sample;\r
- guint64 timestamp, duration, position;\r
- gboolean keyframe;\r
-\r
- GST_DEBUG_OBJECT (demux,\r
- "BEGIN // in MOVIE for offset %" G_GUINT64_FORMAT, demux->offset);\r
-\r
- if (demux->fragmented) {\r
- GST_DEBUG_OBJECT (demux, "mdat remaining %" G_GUINT64_FORMAT,\r
- demux->mdatleft);\r
- if (G_LIKELY (demux->todrop < demux->mdatleft)) {\r
- /* if needed data starts within this atom,\r
- * then it should not exceed this atom */\r
- if (G_UNLIKELY (demux->neededbytes > demux->mdatleft)) {\r
-\r
- GST_ELEMENT_ERROR (demux, STREAM, DEMUX,\r
- ("This file is invalid and cannot be played."),\r
- ("sample data crosses atom boundary"));\r
-\r
- ret = GST_FLOW_ERROR;\r
- break;\r
- }\r
- demux->mdatleft -= demux->neededbytes;\r
- } else {\r
- GST_DEBUG_OBJECT (demux, "data atom emptied; resuming atom scan");\r
- /* so we are dropping more than left in this atom */\r
- demux->todrop -= demux->mdatleft;\r
- demux->neededbytes -= demux->mdatleft;\r
- demux->mdatleft = 0;\r
- /* need to resume atom parsing so we do not miss any other pieces */\r
- demux->state = PIFFDEMUX_STATE_INITIAL;\r
- demux->neededbytes = 16;\r
- break;\r
- }\r
- }\r
-\r
- if (demux->todrop) {\r
- GST_LOG_OBJECT (demux, "Dropping %d bytes", demux->todrop);\r
- gst_adapter_flush (demux->adapter, demux->todrop);\r
- demux->neededbytes -= demux->todrop;\r
- demux->offset += demux->todrop;\r
- }\r
-\r
- if ( !stream->sent_nsevent) {\r
- //TODO: better to parse sink event function and send that new_segment\r
-#if 1\r
- demux->pending_newsegment = gst_event_new_new_segment (FALSE, 1.0, GST_FORMAT_TIME,\r
- demux->stream->start_ts, -1, demux->stream->start_ts);\r
-#else\r
- demux->pending_newsegment = gst_event_new_new_segment (FALSE, 1.0, GST_FORMAT_TIME,\r
- 0, gst_util_uint64_scale (stream->duration, GST_SECOND, stream->timescale), 0);\r
-#endif\r
-\r
- GST_INFO_OBJECT (demux, "New segment event : start = %"GST_TIME_FORMAT", stop = %" GST_TIME_FORMAT,\r
- GST_TIME_ARGS (demux->stream->start_ts), GST_TIME_ARGS(gst_util_uint64_scale (stream->duration, GST_SECOND, stream->timescale)));\r
-\r
- if (!gst_pad_push_event (demux->srcpad, demux->pending_newsegment)) {\r
- GST_ERROR_OBJECT (demux, "failding to send new segment...");\r
- goto newsegment_error;\r
- }\r
- stream->sent_nsevent = TRUE;\r
- }\r
-\r
- /* Put data in a buffer, set timestamps, caps, ... */\r
- outbuf = gst_adapter_take_buffer (demux->adapter, demux->neededbytes);\r
-\r
- GST_DEBUG_OBJECT (demux, "Taken %d size buffer from adapter...", outbuf ? GST_BUFFER_SIZE (outbuf) : 0);\r
- GST_DEBUG_OBJECT (demux, "stream : %" GST_FOURCC_FORMAT, GST_FOURCC_ARGS (stream->fourcc));\r
-\r
- g_return_val_if_fail (outbuf != NULL, GST_FLOW_ERROR);\r
-\r
- sample = &stream->samples[stream->sample_index];\r
-\r
- GST_DEBUG_OBJECT (demux, "start_ts = %"GST_TIME_FORMAT" ts : %"GST_TIME_FORMAT" ts = %llu, pts_offset = %u, scale = %d\n",\r
- GST_TIME_ARGS(stream->start_ts),GST_TIME_ARGS(sample->timestamp), sample->timestamp,\r
- sample->pts_offset,stream->timescale);\r
-\r
- position = PIFFSAMPLE_DTS (stream, sample);\r
- timestamp = PIFFSAMPLE_PTS (stream, sample) + stream->start_ts; // Adding to avoid resetting of timestamp\r
- duration = PIFFSAMPLE_DUR_DTS (stream, sample, position);\r
- keyframe = PIFFSAMPLE_KEYFRAME (stream, sample);\r
-\r
- ret = gst_piffdemux_decorate_and_push_buffer (demux, stream, outbuf,\r
- timestamp, duration, keyframe, position, demux->offset);\r
-\r
- stream->sample_index++;\r
-\r
- /* update current offset and figure out size of next buffer */\r
- GST_LOG_OBJECT (demux, "increasing offset %" G_GUINT64_FORMAT " by %u",\r
- demux->offset, demux->neededbytes);\r
- demux->offset += demux->neededbytes;\r
- GST_LOG_OBJECT (demux, "offset is now %" G_GUINT64_FORMAT,\r
- demux->offset);\r
-\r
- if ((demux->neededbytes = next_entry_size (demux)) == -1) {\r
- GST_DEBUG_OBJECT (demux, "finished parsing mdat, need to search next moof atom");\r
- demux->neededbytes = 16;\r
- demux->state = PIFFDEMUX_STATE_INITIAL;\r
- GST_DEBUG ("\n\n Storing %s last_ts %"GST_TIME_FORMAT"\n\n", stream->subtype == FOURCC_vide ? "video" : "audio", GST_TIME_ARGS(timestamp));\r
- stream->start_ts = timestamp + duration;\r
- //goto eos;\r
- }\r
- break;\r
- }\r
- default:\r
- goto invalid_state;\r
- }\r
- }\r
-\r
- /* when buffering movie data, at least show user something is happening */\r
- if (ret == GST_FLOW_OK && demux->state == PIFFDEMUX_STATE_BUFFER_MDAT &&\r
- gst_adapter_available (demux->adapter) <= demux->neededbytes) {\r
- gst_piffdemux_post_progress (demux, gst_adapter_available (demux->adapter),\r
- demux->neededbytes);\r
- }\r
-done:\r
- gst_object_unref (demux);\r
-\r
- return ret;\r
-\r
- /* ERRORS */\r
-unknown_stream:\r
- {\r
- GST_ELEMENT_ERROR (demux, STREAM, FAILED, (NULL), ("unknown stream found"));\r
- ret = GST_FLOW_ERROR;\r
- goto done;\r
- }\r
-eos:\r
- {\r
- GST_DEBUG_OBJECT (demux, "no next entry, EOS");\r
- ret = GST_FLOW_UNEXPECTED;\r
- goto done;\r
- }\r
-invalid_state:\r
- {\r
- GST_ELEMENT_ERROR (demux, STREAM, FAILED,\r
- (NULL), ("piffdemuxer invalid state %d", demux->state));\r
- ret = GST_FLOW_ERROR;\r
- goto done;\r
- }\r
-newsegment_error:\r
- {\r
- GST_ELEMENT_ERROR (demux, STREAM, FAILED,\r
- (NULL), ("could not send newsegment event"));\r
- ret = GST_FLOW_ERROR;\r
- goto done;\r
- }\r
-}\r
-\r
-static gboolean\r
-piffdemux_parse_container (GstPiffDemux * piffdemux, GNode * node, const guint8 * buf,\r
- const guint8 * end)\r
-{\r
- while (G_UNLIKELY (buf < end)) {\r
- GNode *child;\r
- guint32 len;\r
-\r
- if (G_UNLIKELY (buf + 4 > end)) {\r
- GST_LOG_OBJECT (piffdemux, "buffer overrun");\r
- break;\r
- }\r
- len = PIFF_UINT32 (buf);\r
- if (G_UNLIKELY (len == 0)) {\r
- GST_LOG_OBJECT (piffdemux, "empty container");\r
- break;\r
- }\r
- if (G_UNLIKELY (len < 8)) {\r
- GST_WARNING_OBJECT (piffdemux, "length too short (%d < 8)", len);\r
- break;\r
- }\r
- if (G_UNLIKELY (len > (end - buf))) {\r
- GST_WARNING_OBJECT (piffdemux, "length too long (%d > %d)", len,\r
- (gint) (end - buf));\r
- break;\r
- }\r
-\r
- child = g_node_new ((guint8 *) buf);\r
- g_node_append (node, child);\r
- GST_LOG_OBJECT (piffdemux, "adding new node of len %d", len);\r
- piffdemux_parse_node (piffdemux, child, buf, len);\r
-\r
- buf += len;\r
- }\r
- return TRUE;\r
-}\r
-\r
-\r
-static gboolean\r
-piffdemux_parse_node (GstPiffDemux * piffdemux, GNode * node, const guint8 * buffer,\r
- guint length)\r
-{\r
- guint32 fourcc = 0;\r
- guint32 node_length = 0;\r
- const PiffNodeType *type;\r
- const guint8 *end;\r
-\r
- GST_LOG_OBJECT (piffdemux, "piffdemux_parse buffer %p length %u", buffer, length);\r
-\r
- if (G_UNLIKELY (length < 8))\r
- goto not_enough_data;\r
-\r
- node_length = PIFF_UINT32 (buffer);\r
- fourcc = PIFF_FOURCC (buffer + 4);\r
-\r
- /* ignore empty nodes */\r
- if (G_UNLIKELY (fourcc == 0 || node_length == 8))\r
- return TRUE;\r
-\r
- type = piffdemux_type_get (fourcc);\r
-\r
- end = buffer + length;\r
-\r
- GST_LOG_OBJECT (piffdemux,\r
- "parsing '%" GST_FOURCC_FORMAT "', length=%u, name '%s'",\r
- GST_FOURCC_ARGS (fourcc), node_length, type->name);\r
-\r
- if (node_length > length)\r
- goto broken_atom_size;\r
-\r
- if (type->flags & PIFF_FLAG_CONTAINER) {\r
- piffdemux_parse_container (piffdemux, node, buffer + 8, end);\r
- }\r
- GST_LOG_OBJECT (piffdemux, "parsed '%" GST_FOURCC_FORMAT "'",\r
- GST_FOURCC_ARGS (fourcc));\r
- return TRUE;\r
-\r
-/* ERRORS */\r
-not_enough_data:\r
- {\r
-\r
- GST_ELEMENT_ERROR (piffdemux, STREAM, DEMUX,\r
- ("This file is corrupt and cannot be played."),\r
- ("Not enough data for an atom header, got only %u bytes", length));\r
-\r
- return FALSE;\r
- }\r
-broken_atom_size:\r
- {\r
- GST_ELEMENT_ERROR (piffdemux, STREAM, DEMUX,\r
- ("This file is corrupt and cannot be played."),\r
- ("Atom '%" GST_FOURCC_FORMAT "' has size of %u bytes, but we have only "\r
- "%u bytes available.", GST_FOURCC_ARGS (fourcc), node_length,\r
- length));\r
-\r
- return FALSE;\r
- }\r
-}\r
-\r
-\r
-static GNode *\r
-piffdemux_tree_get_child_by_type (GNode * node, guint32 fourcc)\r
-{\r
- GNode *child;\r
- guint8 *buffer;\r
- guint32 child_fourcc;\r
-\r
- for (child = g_node_first_child (node); child;\r
- child = g_node_next_sibling (child)) {\r
- buffer = (guint8 *) child->data;\r
-\r
- child_fourcc = PIFF_FOURCC (buffer + 4);\r
-\r
- if (G_UNLIKELY (child_fourcc == fourcc)) {\r
- return child;\r
- }\r
- }\r
- return NULL;\r
-}\r
-\r
-static GNode *\r
-piffdemux_tree_get_child_by_type_full (GNode * node, guint32 fourcc,\r
- GstByteReader * parser)\r
-{\r
- GNode *child;\r
- guint8 *buffer;\r
- guint32 child_fourcc, child_len;\r
-\r
- for (child = g_node_first_child (node); child;\r
- child = g_node_next_sibling (child)) {\r
- buffer = (guint8 *) child->data;\r
-\r
- child_len = PIFF_UINT32 (buffer);\r
- child_fourcc = PIFF_FOURCC (buffer + 4);\r
-\r
- if (G_UNLIKELY (child_fourcc == fourcc)) {\r
- if (G_UNLIKELY (child_len < (4 + 4)))\r
- return NULL;\r
- /* FIXME: must verify if atom length < parent atom length */\r
- gst_byte_reader_init (parser, buffer + (4 + 4), child_len - (4 + 4));\r
- return child;\r
- }\r
- }\r
- return NULL;\r
-}\r
-\r
-static GNode *\r
-piffdemux_tree_get_sibling_by_type_full (GNode * node, guint32 fourcc,\r
- GstByteReader * parser)\r
-{\r
- GNode *child;\r
- guint8 *buffer;\r
- guint32 child_fourcc, child_len;\r
-\r
- for (child = g_node_next_sibling (node); child;\r
- child = g_node_next_sibling (child)) {\r
- buffer = (guint8 *) child->data;\r
-\r
- child_fourcc = PIFF_FOURCC (buffer + 4);\r
-\r
- if (child_fourcc == fourcc) {\r
- if (parser) {\r
- child_len = PIFF_UINT32 (buffer);\r
- if (G_UNLIKELY (child_len < (4 + 4)))\r
- return NULL;\r
- /* FIXME: must verify if atom length < parent atom length */\r
- gst_byte_reader_init (parser, buffer + (4 + 4), child_len - (4 + 4));\r
- }\r
- return child;\r
- }\r
- }\r
- return NULL;\r
-}\r
-\r
-static GNode *\r
-piffdemux_tree_get_sibling_by_type (GNode * node, guint32 fourcc)\r
-{\r
- return piffdemux_tree_get_sibling_by_type_full (node, fourcc, NULL);\r
-}\r
-\r
-#define _codec(name) \\r
- do { \\r
- if (codec_name) { \\r
- *codec_name = g_strdup (name); \\r
- } \\r
- } while (0)\r
-\r
-void\r
-gst_piffdemux_set_video_params (GstPiffDemux * piffdemux, guint fourcc,\r
- guint width, guint height,\r
- guint fps_n, guint fps_d, unsigned char *codec_data, unsigned int codec_data_len)\r
-{\r
- GstCaps *caps = NULL;\r
- GstBuffer *dci = NULL;\r
-\r
- if (codec_data && codec_data_len) {\r
- dci = gst_buffer_new_and_alloc (codec_data_len);\r
- if (!dci) {\r
- GST_ERROR_OBJECT (piffdemux, "failed to create codec data buffer...");\r
- } else {\r
- memcpy (GST_BUFFER_DATA(dci), codec_data, codec_data_len);\r
- }\r
- }\r
-\r
- switch (fourcc) {\r
-\r
- case GST_MAKE_FOURCC ('a', 'v', 'c', '1'):\r
- caps = gst_caps_new_simple ("video/x-h264",\r
- "width", G_TYPE_INT, width,\r
- "height", G_TYPE_INT, height,\r
- "framerate", GST_TYPE_FRACTION, fps_n, fps_d,\r
- "stream-format", G_TYPE_STRING, "avc",\r
- "alignment", G_TYPE_STRING, "au",\r
- "codec_data", GST_TYPE_BUFFER, dci,\r
- NULL);\r
- break;\r
-\r
- case FOURCC_ovc1:\r
- caps = gst_caps_new_simple ("video/x-wmv",\r
- "width", G_TYPE_INT, width,\r
- "height", G_TYPE_INT, height,\r
- "framerate", GST_TYPE_FRACTION, fps_n, fps_d,\r
- "wmvversion", G_TYPE_INT, 3,\r
- "format", GST_TYPE_FOURCC, GST_MAKE_FOURCC ('W', 'V', 'C', '1'),\r
- "codec_data", GST_TYPE_BUFFER, dci,\r
- NULL);\r
- break;\r
-\r
- default: {\r
- char *s;\r
- s = g_strdup_printf ("video/x-gst-fourcc-%" GST_FOURCC_FORMAT,\r
- GST_FOURCC_ARGS (fourcc));\r
- caps = gst_caps_new_simple (s,\r
- "width", G_TYPE_INT, width,\r
- "height", G_TYPE_INT, height,\r
- "framerate", GST_TYPE_FRACTION, fps_n, fps_d,\r
- "codec_data", GST_TYPE_BUFFER, dci,\r
- NULL);\r
- break;\r
- }\r
- }\r
-\r
- piffdemux->stream->caps = caps;\r
- GST_INFO_OBJECT (piffdemux, "prepared video caps : %s", gst_caps_to_string(caps));\r
-}\r
-\r
-void\r
-gst_piffdemux_set_audio_params (GstPiffDemux * piffdemux, guint fourcc,\r
- guint sampling_rate, guint bps, guint channels, unsigned char *codec_data, unsigned int codec_data_len)\r
-{\r
- GstCaps *caps = NULL;\r
- GstBuffer *dci = NULL;\r
-\r
- if (codec_data && codec_data_len) {\r
- dci = gst_buffer_new_and_alloc (codec_data_len);\r
- if (!dci) {\r
- GST_ERROR_OBJECT (piffdemux, "failed to create codec data buffer...");\r
- } else {\r
- memcpy (GST_BUFFER_DATA(dci), codec_data, codec_data_len);\r
- }\r
- }\r
-\r
- switch (fourcc) {\r
-\r
- case GST_MAKE_FOURCC ('m', 'p', '4', 'a'):\r
- caps = gst_caps_new_simple ("audio/mpeg",\r
- "mpegversion", G_TYPE_INT, 4,\r
- "framed", G_TYPE_BOOLEAN, TRUE,\r
- "stream-format", G_TYPE_STRING, "raw",\r
- "rate", G_TYPE_INT, (int) sampling_rate,\r
- "channels", G_TYPE_INT, channels,\r
- NULL);\r
- break;\r
-\r
- case FOURCC_owma:\r
- caps = gst_caps_new_simple ("audio/x-wma",\r
- "rate", G_TYPE_INT, (int) sampling_rate,\r
- "channels", G_TYPE_INT, channels,\r
- NULL);\r
- break;\r
-\r
- default: {\r
- char *s;\r
- s = g_strdup_printf ("audio/x-gst-fourcc-%" GST_FOURCC_FORMAT,\r
- GST_FOURCC_ARGS (fourcc));\r
- caps = gst_caps_new_simple (s,\r
- "rate", G_TYPE_INT, (int) sampling_rate,\r
- "channels", G_TYPE_INT, channels,\r
- NULL);\r
- break;\r
- }\r
- }\r
-\r
- piffdemux->stream->caps = caps;\r
- GST_INFO_OBJECT (piffdemux, "prepared audio caps : %s", gst_caps_to_string(caps));\r
-\r
-}\r
-\r
-#define g_marshal_value_peek_object(v) g_value_get_object (v)\r
-\r
-void\r
-__gst_piffdemux_marshal_BOOLEAN__OBJECT (GClosure *closure,\r
- GValue *return_value G_GNUC_UNUSED,\r
- guint n_param_values,\r
- const GValue *param_values,\r
- gpointer invocation_hint G_GNUC_UNUSED,\r
- gpointer marshal_data)\r
-{\r
- typedef gboolean (*GMarshalFunc_BOOLEAN__OBJECT) (gpointer data1,\r
- gpointer arg_1,\r
- gpointer data2);\r
- register GMarshalFunc_BOOLEAN__OBJECT callback;\r
- register GCClosure *cc = (GCClosure*) closure;\r
- register gpointer data1, data2;\r
- gboolean v_return;\r
-\r
- g_return_if_fail (return_value != NULL);\r
- g_return_if_fail (n_param_values == 2);\r
-\r
- if (G_CCLOSURE_SWAP_DATA (closure))\r
- {\r
- data1 = closure->data;\r
- data2 = g_value_peek_pointer (param_values + 0);\r
- }\r
- else\r
- {\r
- data1 = g_value_peek_pointer (param_values + 0);\r
- data2 = closure->data;\r
- }\r
- callback = (GMarshalFunc_BOOLEAN__OBJECT) (marshal_data ? marshal_data : cc->callback);\r
-\r
- v_return = callback (data1,\r
- g_marshal_value_peek_object (param_values + 1),\r
- data2);\r
-\r
- g_value_set_boolean (return_value, v_return);\r
-}\r
-\r
-#define PIFFDEMUX_SPSPPS_LENGTH_SIZE 2\r
-\r
-static gboolean\r
-ConvertH264_MetaDCI_to_3GPPDCI(unsigned char *dci_meta_buf, unsigned int dci_meta_size, unsigned char **dci_3gpp_buf, unsigned int *dci_3gpp_size)\r
-{\r
- unsigned short unit_size = 0;\r
- unsigned int total_size = 0;\r
- unsigned char unit_nb = 0;\r
- unsigned char sps_done = 0;\r
- const unsigned char *extradata = NULL;\r
- unsigned int h264_nal_length_size = 0;\r
- unsigned char *out = NULL;\r
- //g_print ("\n\nConvertH264_MetaDCI_to_3GPPDCI Entering.............\n");\r
-\r
- /* nothing to filter */\r
- if ((dci_meta_buf == NULL) || (dci_meta_size < 6))\r
- {\r
- GST_ERROR ("Insufficient codec data...\n");\r
- return FALSE;\r
- }\r
-\r
- /* Removing unnecessary info in meta data */\r
- extradata = (unsigned char *)dci_meta_buf + 4;\r
-\r
- /* retrieve Length of Length*/\r
- h264_nal_length_size = (*extradata++ & 0x03) + 1;\r
-\r
- GST_LOG ("Length Of Length is %d\n", h264_nal_length_size);\r
- if (h264_nal_length_size == 3)\r
- {\r
- GST_ERROR ("LengthOfLength is WRONG...\n");\r
- return FALSE;\r
- }\r
-\r
- /* retrieve sps and pps unit(s) */\r
- unit_nb = *extradata++ & 0x1f; /* number of sps unit(s) */\r
- GST_LOG ("No. of SPS units = %u\n", unit_nb);\r
-\r
- if (!unit_nb)\r
- {\r
- GST_ERROR ("SPS is not present....\n");\r
- return FALSE;\r
- }\r
-\r
- while (unit_nb--)\r
- {\r
- /* get SPS/PPS data Length*/\r
- unit_size = PIFFDEMUX_RB16(extradata);\r
-\r
- GST_LOG ("SPS size = %d", unit_size);\r
-\r
- /* Extra 4 bytes for adding size of the packet */\r
- total_size += unit_size + h264_nal_length_size;\r
-\r
- /* Check if SPS/PPS Data Length crossed buffer Length */\r
- if ((extradata + 2 + unit_size) > (dci_meta_buf + dci_meta_size))\r
- {\r
- GST_ERROR ("SPS Length is wrong in DCI...\n");\r
- return FALSE;\r
- }\r
- out = realloc(out, total_size);\r
- if (!out)\r
- {\r
- GST_ERROR ("realloc FAILED...\n");\r
- return FALSE;\r
- }\r
- /* Copy length of SPS header */\r
- // tmp = (unsigned int *)(out + total_size - unit_size - h264_nal_length_size);\r
- // *tmp = unit_size; \r
- (out + total_size - unit_size - h264_nal_length_size)[0] = 0;\r
- (out + total_size - unit_size - h264_nal_length_size)[1] = 0;\r
- (out + total_size - unit_size - h264_nal_length_size)[2] = 0;\r
- (out + total_size - unit_size - h264_nal_length_size)[3] = (unsigned char)unit_size;\r
-\r
- // memcpy(out + total_size - unit_size - h264_nal_length_size, &unit_size, h264_nal_length_size);\r
- //g_print ("out[0] = %02x, out[1] = %02x, out[2] = %02x = out[3] = %02x\n",\r
- // out[total_size - unit_size - h264_nal_length_size], out[total_size - unit_size - h264_nal_length_size+1],\r
- // out[total_size - unit_size - h264_nal_length_size + 2], out[total_size - unit_size - h264_nal_length_size + 3]);\r
-\r
- /* Copy SPS/PPS Length and data */\r
- memcpy(out + total_size - unit_size, extradata + PIFFDEMUX_SPSPPS_LENGTH_SIZE, unit_size);\r
-\r
- extradata += (PIFFDEMUX_SPSPPS_LENGTH_SIZE + unit_size);\r
-\r
- if (!unit_nb && !sps_done++)\r
- {\r
- /* Completed reading SPS data, now read PPS data */\r
- unit_nb = *extradata++; /* number of pps unit(s) */\r
- GST_DEBUG ("No. of PPS units = %d\n", unit_nb);\r
- }\r
- }\r
-\r
- *dci_3gpp_buf = malloc (total_size);\r
- if (NULL == *dci_3gpp_buf)\r
- {\r
- GST_ERROR ("Memory Allocation FAILED...\n");\r
- free (out);\r
- return FALSE;\r
- }\r
-\r
- memcpy(*dci_3gpp_buf, out, total_size);\r
- *dci_3gpp_size = total_size;\r
-\r
- GST_DEBUG ("SPS_PPS size = %d\n", total_size);\r
-\r
- if (out)\r
- {\r
- free(out);\r
- }\r
- return TRUE;\r
- }\r
-\r