diff --git a/media-video/ffmpeg/additional-files/gcc_runtime.c b/media-video/ffmpeg/additional-files/gcc_runtime.c new file mode 100644 index 000000000..b53c82ac6 --- /dev/null +++ b/media-video/ffmpeg/additional-files/gcc_runtime.c @@ -0,0 +1,404 @@ +// Functions here copied from gcc/libgcc/libgcc2.c unless otherwise noted. + +/* Copyright (C) 1989-2018 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC 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. + +Under Section 7 of GPL version 3, you are granted additional +permissions described in the GCC Runtime Library Exception, version +3.1, as published by the Free Software Foundation. + +You should have received a copy of the GNU General Public License and +a copy of the GCC Runtime Library Exception along with this program; +see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +. */ + +#if __GNUC__ == 2 +#define __CHAR_BIT__ 8 +#endif + +// from gcc/config/i386/i386.h +#define MIN_UNITS_PER_WORD 4 + + +#if MIN_UNITS_PER_WORD > 4 +# define LIBGCC2_MAX_UNITS_PER_WORD 8 +#elif (MIN_UNITS_PER_WORD > 2 \ + || (MIN_UNITS_PER_WORD > 1 && __SIZEOF_LONG_LONG__ > 4)) +# define LIBGCC2_MAX_UNITS_PER_WORD 4 +#else +# define LIBGCC2_MAX_UNITS_PER_WORD MIN_UNITS_PER_WORD +#endif + +#ifndef LIBGCC2_UNITS_PER_WORD +#define LIBGCC2_UNITS_PER_WORD LIBGCC2_MAX_UNITS_PER_WORD +#endif + +#if LIBGCC2_UNITS_PER_WORD == 8 +#define W_TYPE_SIZE (8 * __CHAR_BIT__) +#define Wtype DItype +#define UWtype UDItype +#define HWtype DItype +#define UHWtype UDItype +#define DWtype TItype +#define UDWtype UTItype +#define COMPAT_SIMODE_TRAPPING_ARITHMETIC +#elif LIBGCC2_UNITS_PER_WORD == 4 +#define W_TYPE_SIZE (4 * __CHAR_BIT__) +#define Wtype SItype +#define UWtype USItype +#define HWtype SItype +#define UHWtype USItype +#define DWtype DItype +#define UDWtype UDItype +#elif LIBGCC2_UNITS_PER_WORD == 2 +#define W_TYPE_SIZE (2 * __CHAR_BIT__) +#define Wtype HItype +#define UWtype UHItype +#define HWtype HItype +#define UHWtype UHItype +#define DWtype SItype +#define UDWtype USItype +#else +#define W_TYPE_SIZE __CHAR_BIT__ +#define Wtype QItype +#define UWtype UQItype +#define HWtype QItype +#define UHWtype UQItype +#define DWtype HItype +#define UDWtype UHItype +#endif + +typedef int QItype __attribute__ ((mode (QI))); +typedef unsigned int UQItype __attribute__ ((mode (QI))); +typedef int HItype __attribute__ ((mode (HI))); +typedef unsigned int UHItype __attribute__ ((mode (HI))); +#if MIN_UNITS_PER_WORD > 1 +/* These typedefs are usually forbidden on dsp's with UNITS_PER_WORD 1. */ +typedef int SItype __attribute__ ((mode (SI))); +typedef unsigned int USItype __attribute__ ((mode (SI))); +#if __SIZEOF_LONG_LONG__ > 4 +/* These typedefs are usually forbidden on archs with UNITS_PER_WORD 2. */ +typedef int DItype __attribute__ ((mode (DI))); +typedef unsigned int UDItype __attribute__ ((mode (DI))); +#if MIN_UNITS_PER_WORD > 4 +/* These typedefs are usually forbidden on archs with UNITS_PER_WORD 4. */ +typedef int TItype __attribute__ ((mode (TI))); +typedef unsigned int UTItype __attribute__ ((mode (TI))); +#endif +#endif +#endif + +#if __BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__ + struct DWstruct {Wtype high, low;}; +#else + struct DWstruct {Wtype low, high;}; +#endif + +typedef union +{ + struct DWstruct s; + DWtype ll; +} DWunion; + +#if (defined (__i386__) || defined (__i486__)) && W_TYPE_SIZE == 32 +#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ + __asm__ ("add{l} {%5,%1|%1,%5}\n\tadc{l} {%3,%0|%0,%3}" \ + : "=r" ((USItype) (sh)), \ + "=&r" ((USItype) (sl)) \ + : "%0" ((USItype) (ah)), \ + "g" ((USItype) (bh)), \ + "%1" ((USItype) (al)), \ + "g" ((USItype) (bl))) +#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ + __asm__ ("sub{l} {%5,%1|%1,%5}\n\tsbb{l} {%3,%0|%0,%3}" \ + : "=r" ((USItype) (sh)), \ + "=&r" ((USItype) (sl)) \ + : "0" ((USItype) (ah)), \ + "g" ((USItype) (bh)), \ + "1" ((USItype) (al)), \ + "g" ((USItype) (bl))) +#define umul_ppmm(w1, w0, u, v) \ + __asm__ ("mul{l} %3" \ + : "=a" ((USItype) (w0)), \ + "=d" ((USItype) (w1)) \ + : "%0" ((USItype) (u)), \ + "rm" ((USItype) (v))) +#define udiv_qrnnd(q, r, n1, n0, dv) \ + __asm__ ("div{l} %4" \ + : "=a" ((USItype) (q)), \ + "=d" ((USItype) (r)) \ + : "0" ((USItype) (n0)), \ + "1" ((USItype) (n1)), \ + "rm" ((USItype) (dv))) +#define count_leading_zeros(count, x) ((count) = __builtin_clz (x)) +#define count_trailing_zeros(count, x) ((count) = __builtin_ctz (x)) +#define UMUL_TIME 40 +#define UDIV_TIME 40 +#endif /* 80x86 */ + +#define UDIV_NEEDS_NORMALIZATION 0 + + +UDWtype +__udivmoddi4 (UDWtype n, UDWtype d, UDWtype *rp) +{ + const DWunion nn = {.ll = n}; + const DWunion dd = {.ll = d}; + DWunion rr; + UWtype d0, d1, n0, n1, n2; + UWtype q0, q1; + UWtype b, bm; + + d0 = dd.s.low; + d1 = dd.s.high; + n0 = nn.s.low; + n1 = nn.s.high; + +#if !UDIV_NEEDS_NORMALIZATION + if (d1 == 0) + { + if (d0 > n1) + { + /* 0q = nn / 0D */ + + udiv_qrnnd (q0, n0, n1, n0, d0); + q1 = 0; + + /* Remainder in n0. */ + } + else + { + /* qq = NN / 0d */ + + if (d0 == 0) + d0 = 1 / d0; /* Divide intentionally by zero. */ + + udiv_qrnnd (q1, n1, 0, n1, d0); + udiv_qrnnd (q0, n0, n1, n0, d0); + + /* Remainder in n0. */ + } + + if (rp != 0) + { + rr.s.low = n0; + rr.s.high = 0; + *rp = rr.ll; + } + } + +#else /* UDIV_NEEDS_NORMALIZATION */ + + if (d1 == 0) + { + if (d0 > n1) + { + /* 0q = nn / 0D */ + + count_leading_zeros (bm, d0); + + if (bm != 0) + { + /* Normalize, i.e. make the most significant bit of the + denominator set. */ + + d0 = d0 << bm; + n1 = (n1 << bm) | (n0 >> (W_TYPE_SIZE - bm)); + n0 = n0 << bm; + } + + udiv_qrnnd (q0, n0, n1, n0, d0); + q1 = 0; + + /* Remainder in n0 >> bm. */ + } + else + { + /* qq = NN / 0d */ + + if (d0 == 0) + d0 = 1 / d0; /* Divide intentionally by zero. */ + + count_leading_zeros (bm, d0); + + if (bm == 0) + { + /* From (n1 >= d0) /\ (the most significant bit of d0 is set), + conclude (the most significant bit of n1 is set) /\ (the + leading quotient digit q1 = 1). + This special case is necessary, not an optimization. + (Shifts counts of W_TYPE_SIZE are undefined.) */ + + n1 -= d0; + q1 = 1; + } + else + { + /* Normalize. */ + + b = W_TYPE_SIZE - bm; + + d0 = d0 << bm; + n2 = n1 >> b; + n1 = (n1 << bm) | (n0 >> b); + n0 = n0 << bm; + + udiv_qrnnd (q1, n1, n2, n1, d0); + } + + /* n1 != d0... */ + + udiv_qrnnd (q0, n0, n1, n0, d0); + + /* Remainder in n0 >> bm. */ + } + + if (rp != 0) + { + rr.s.low = n0 >> bm; + rr.s.high = 0; + *rp = rr.ll; + } + } +#endif /* UDIV_NEEDS_NORMALIZATION */ + + else + { + if (d1 > n1) + { + /* 00 = nn / DD */ + + q0 = 0; + q1 = 0; + + /* Remainder in n1n0. */ + if (rp != 0) + { + rr.s.low = n0; + rr.s.high = n1; + *rp = rr.ll; + } + } + else + { + /* 0q = NN / dd */ + + count_leading_zeros (bm, d1); + if (bm == 0) + { + /* From (n1 >= d1) /\ (the most significant bit of d1 is set), + conclude (the most significant bit of n1 is set) /\ (the + quotient digit q0 = 0 or 1). + This special case is necessary, not an optimization. */ + + /* The condition on the next line takes advantage of that + n1 >= d1 (true due to program flow). */ + if (n1 > d1 || n0 >= d0) + { + q0 = 1; + sub_ddmmss (n1, n0, n1, n0, d1, d0); + } + else + q0 = 0; + + q1 = 0; + + if (rp != 0) + { + rr.s.low = n0; + rr.s.high = n1; + *rp = rr.ll; + } + } + else + { + UWtype m1, m0; + /* Normalize. */ + + b = W_TYPE_SIZE - bm; + + d1 = (d1 << bm) | (d0 >> b); + d0 = d0 << bm; + n2 = n1 >> b; + n1 = (n1 << bm) | (n0 >> b); + n0 = n0 << bm; + + udiv_qrnnd (q0, n1, n2, n1, d1); + umul_ppmm (m1, m0, q0, d0); + + if (m1 > n1 || (m1 == n1 && m0 > n0)) + { + q0--; + sub_ddmmss (m1, m0, m1, m0, d1, d0); + } + + q1 = 0; + + /* Remainder in (n1n0 - m1m0) >> bm. */ + if (rp != 0) + { + sub_ddmmss (n1, n0, n1, n0, m1, m0); + rr.s.low = (n1 << b) | (n0 >> bm); + rr.s.high = n1 >> bm; + *rp = rr.ll; + } + } + } + } + + const DWunion ww = {{.low = q0, .high = q1}}; + return ww.ll; +} + +DWtype +__divmoddi4 (DWtype u, DWtype v, DWtype *rp) +{ + Wtype c1 = 0, c2 = 0; + DWunion uu = {.ll = u}; + DWunion vv = {.ll = v}; + DWtype w; + DWtype r; + + if (uu.s.high < 0) + c1 = ~c1, c2 = ~c2, + uu.ll = -uu.ll; + if (vv.s.high < 0) + c1 = ~c1, + vv.ll = -vv.ll; + + w = __udivmoddi4 (uu.ll, vv.ll, (UDWtype*)&r); + if (c1) + w = -w; + if (c2) + r = -r; + + *rp = r; + return w; +} + +int +__ctzdi2 (UDWtype x) +{ + const DWunion uu = {.ll = x}; + UWtype word; + Wtype ret, add; + + if (uu.s.low) + word = uu.s.low, add = 0; + else + word = uu.s.high, add = W_TYPE_SIZE; + + count_trailing_zeros (ret, word); + return ret + add; +} diff --git a/media-video/ffmpeg/ffmpeg-4.0.1.recipe b/media-video/ffmpeg/ffmpeg-4.0.1.recipe index 32b552ef0..c5e697cd4 100644 --- a/media-video/ffmpeg/ffmpeg-4.0.1.recipe +++ b/media-video/ffmpeg/ffmpeg-4.0.1.recipe @@ -7,13 +7,14 @@ COPYRIGHT="2000-2003 Fabrice Bellard 2003-2018 the FFmpeg developers" LICENSE="GNU LGPL v3 GNU GPL v3" -REVISION="1" +REVISION="2" SOURCE_URI="https://ffmpeg.org/releases/ffmpeg-$portVersion.tar.xz" CHECKSUM_SHA256="605f5c01c60db35d3b617a79cabb2c7032412be243554602eeed1b628125c0ee" PATCHES="ffmpeg-$portVersion.patchset" +ADDITIONAL_FILES="gcc_runtime.c" -ARCHITECTURES="!x86_gcc2 x86 x86_64" -SECONDARY_ARCHITECTURES="!x86_gcc2 x86" +ARCHITECTURES="x86_gcc2 x86 x86_64" +SECONDARY_ARCHITECTURES="x86_gcc2 x86" ffmpegLibs="\ libavcodec \ @@ -42,7 +43,7 @@ for i in $ffmpegLibs; do done PROVIDES=" - ffmpeg4$secondaryArchSuffix = $portVersionCompat + ffmpeg$secondaryArchSuffix = $portVersionCompat lib:libavcodec$secondaryArchSuffix = $libavcodecVersionCompat lib:libavfilter$secondaryArchSuffix = $libavfilterVersionCompat lib:libavformat$secondaryArchSuffix = $libavformatVersionCompat @@ -55,7 +56,6 @@ PROVIDES=" REQUIRES=" haiku$secondaryArchSuffix lib:libbz2$secondaryArchSuffix - lib:libgnutls$secondaryArchSuffix lib:libmodplug$secondaryArchSuffix lib:libogg$secondaryArchSuffix lib:libspeex$secondaryArchSuffix @@ -63,9 +63,14 @@ REQUIRES=" lib:libtheoraenc$secondaryArchSuffix lib:libvorbis$secondaryArchSuffix lib:libvorbisenc$secondaryArchSuffix - lib:libvpx$secondaryArchSuffix lib:libz$secondaryArchSuffix " +if [ "$effectiveTargetArchitecture" != x86_gcc2 ]; then + REQUIRES+=" + lib:libvpx$secondaryArchSuffix + lib:libgnutls$secondaryArchSuffix + " +fi CONFLICTS=" ffmpeg_legacy$secondaryArchSuffix ffmpeg${secondaryArchSuffix}_bin @@ -73,7 +78,7 @@ CONFLICTS=" " PROVIDES_avdevice=" - ffmpeg4${secondaryArchSuffix}_avdevice = $portVersionCompat + ffmpeg${secondaryArchSuffix}_avdevice = $portVersionCompat lib:libavdevice$secondaryArchSuffix = $libavdeviceVersionCompat " REQUIRES_avdevice=" @@ -86,7 +91,7 @@ REQUIRES_avdevice=" " PROVIDES_tools=" - ffmpeg4${secondaryArchSuffix}_tools = $portVersion + ffmpeg${secondaryArchSuffix}_tools = $portVersion cmd:ffmpeg = $portVersionCompat cmd:ffplay = $portVersionCompat cmd:ffprobe = $portVersionCompat @@ -102,7 +107,7 @@ REQUIRES_tools=" " PROVIDES_devel=" - ffmpeg4${secondaryArchSuffix}_devel = $portVersionCompat + ffmpeg${secondaryArchSuffix}_devel = $portVersionCompat devel:libavcodec$secondaryArchSuffix = $libavcodecVersionCompat devel:libavdevice$secondaryArchSuffix = $libavdeviceVersionCompat devel:libavfilter$secondaryArchSuffix = $libavfilterVersionCompat @@ -114,7 +119,7 @@ PROVIDES_devel=" devel:libswscale$secondaryArchSuffix = $libswscaleVersionCompat " REQUIRES_devel=" - ffmpeg4$secondaryArchSuffix == $portVersion base + ffmpeg$secondaryArchSuffix == $portVersion base devel:libspeex$secondaryArchSuffix " CONFLICTS_devel=" @@ -123,25 +128,48 @@ CONFLICTS_devel=" ffmpeg2${secondaryArchSuffix}_devel " +# -- HACK! -- +# ffmpeg ~0.10 has perpetually had & caused problems when compiled with GCC 2. +# (Later versions do not compile with GCC 2 at all.) So instead, we now compile +# FFmpeg for x86_gcc2 with a modern GCC. +# +# This works because GCC's C ABI has not changed between 2 and 7; only the C++ +# ABI has, and no BeOS applications expect a system FFmpeg at all, so we can +# break its ABI all we like. +if [ "$effectiveTargetArchitecture" = x86_gcc2 ] && \ + [ "$targetArchitecture" = x86_gcc2 ]; then + gccSuffix="_x86" +elif [ "$effectiveTargetArchitecture" = x86_gcc2 ] && \ + [ "$targetArchitecture" = x86 ]; then + gccSuffix="" +else + gccSuffix="$secondaryArchSuffix" +fi + BUILD_REQUIRES=" haiku${secondaryArchSuffix}_devel devel:libbz2$secondaryArchSuffix - devel:libgnutls$secondaryArchSuffix devel:libmodplug$secondaryArchSuffix devel:libogg$secondaryArchSuffix devel:libsdl2$secondaryArchSuffix devel:libspeex$secondaryArchSuffix devel:libtheora$secondaryArchSuffix devel:libvorbis$secondaryArchSuffix - devel:libvpx$secondaryArchSuffix devel:libz$secondaryArchSuffix " +if [ "$effectiveTargetArchitecture" != x86_gcc2 ]; then + BUILD_REQUIRES+=" + devel:libvpx$secondaryArchSuffix + devel:libgnutls$secondaryArchSuffix + " +fi BUILD_PREREQUIRES=" cmd:awk cmd:cmp - cmd:gcc$secondaryArchSuffix >= 7 + cmd:gcc$gccSuffix >= 7 + cmd:g++$secondaryArchSuffix + cmd:ld$gccSuffix cmd:grep - cmd:ld$secondaryArchSuffix cmd:make cmd:perl cmd:pkg_config$secondaryArchSuffix @@ -156,9 +184,14 @@ PATCH() sed -i "s,/usr/bin/perl,$portPackageLinksDir/cmd~perl/bin/perl," \ doc/Doxyfile \ doc/texi2pod.pl + # force no-undefined-symbols + if [ "$effectiveTargetArchitecture" = x86_gcc2 ]; then + sed -i "s/SHFLAGS='-shared/SHFLAGS='-shared -Wl,--no-undefined/g" \ + configure + fi } -defineDebugInfoPackage ffmpeg4$secondaryArchSuffix \ +defineDebugInfoPackage ffmpeg$secondaryArchSuffix \ $libDir/libavcodec.so.$libavcodecVersion \ $libDir/libavfilter.so.$libavfilterVersion \ $libDir/libavformat.so.$libavformatVersion \ @@ -168,16 +201,46 @@ defineDebugInfoPackage ffmpeg4$secondaryArchSuffix \ $libDir/libswresample.so.$libswresampleVersion \ $libDir/libswscale.so.$libswscaleVersion \ "$(getPackagePrefix avdevice)/$relativeLibDir"/libavdevice.so.$libavdeviceVersion \ - "$(getPackagePrefix tools)/bin"/ffmpeg \ - "$(getPackagePrefix tools)/bin"/ffplay \ - "$(getPackagePrefix tools)/bin"/ffprobe + "$(getPackagePrefix tools)/$relativeBinDir"/ffmpeg \ + "$(getPackagePrefix tools)/$relativeBinDir"/ffplay \ + "$(getPackagePrefix tools)/$relativeBinDir"/ffprobe BUILD() { + ccArgs="" + extraArgs="" + if [ "$effectiveTargetArchitecture" = x86_gcc2 ]; then + cc="gcc${gccSuffix/_/-}" + ccArgs="--cc=$cc --cxx=g++${secondaryArchSuffix/_/-} + --ld=gcc${secondaryArchSuffix/_/-} + --host-ld=gcc${secondaryArchSuffix/_/-}" + + # Hack up base headers to make them think we're on GCC2 ABI + mkdir -p include_hacks include_hacks/os include_hacks/config + pushd include_hacks + rm -f os/BeBuild.h config/HaikuConfig.h + cp /system/develop/headers/os/BeBuild.h os + cp /system/develop/headers/config/HaikuConfig.h config + sed -i 's/__GNUC__ == 2/1/g' os/BeBuild.h config/HaikuConfig.h + popd + + # Compile gcc_runtime.c (subset of libgcc that GCC 7 utilizes here) + $cc -fvisibility=hidden -c $portDir/additional-files/gcc_runtime.c \ + -o gcc_runtime.o + + baseLDFLAGS="-B/system/bin/${gccSuffix/_/}" + ccArgs="$ccArgs --host-ldflags=\"${baseLDFLAGS}\"" + export CFLAGS="-isystem$(pwd) -isystem$(pwd)/os -isystem$(pwd)/config" + export LDFLAGS="$baseLDFLAGS $(pwd)/gcc_runtime.o" + else + extraArgs="--enable-libvpx --enable-gnutls" + fi + # not an autotools configure ./configure \ + $ccArgs \ --prefix=$prefix \ - --bindir=$prefix/bin \ + --bindir=$binDir \ --datadir=$dataDir/$portName \ --incdir=$includeDir \ --libdir=$libDir \ @@ -188,13 +251,13 @@ BUILD() --enable-gpl \ --enable-version3 \ --enable-shared \ + --disable-static \ --enable-libmodplug \ --enable-libvorbis \ --enable-libspeex \ --enable-libtheora \ - --enable-libvpx \ --enable-avresample \ - --enable-gnutls + $extraArgs make $jobArgs } @@ -223,7 +286,7 @@ INSTALL() rm -r $prefix/share # Split out libs and executables which need libSDL - packageEntries tools $prefix/bin + packageEntries tools $binDir packageEntries avdevice $libDir/libavdevice* # devel package