SUMMARY="Audio and video recording, conversion, and streaming library"
DESCRIPTION="FFmpeg is a complete, cross-platform solution to record, convert \
and stream audio and video. It includes libavcodec - the leading audio/video \
codec library."
HOMEPAGE="https://ffmpeg.org/"
COPYRIGHT="2000-2003 Fabrice Bellard
	2003-2020 the FFmpeg developers"
LICENSE="GNU LGPL v3"
REVISION="2"
SOURCE_URI="https://ffmpeg.org/releases/ffmpeg-$portVersion.tar.xz"
CHECKSUM_SHA256="1d0ad06484f44bcb97eba5e93c40bcb893890f9f64aeb43e46cd9bb4cbd6795d"
PATCHES="ffmpeg-$portVersion.patchset"
ADDITIONAL_FILES="gcc_runtime.c"

ARCHITECTURES="!all x86"
SECONDARY_ARCHITECTURES="x86_gcc2 !x86"

ffmpegLibs="\
	libavcodec \
	libavdevice \
	libavfilter \
	libavformat \
	libavutil \
	libswresample \
	libswscale \
	"
# Do not sort alphabetically
libavutilVersion="56.51.100"
libavcodecVersion="58.91.100"
libavformatVersion="58.45.100"
libavdeviceVersion="58.10.100"
libavfilterVersion="7.85.100"
libswscaleVersion="5.7.100"
libswresampleVersion="3.7.100"
portVersionCompat="$portVersion compat >= 4"
for i in $ffmpegLibs; do
	eval "${i}VersionCompat=\"\$${i}Version compat >= \${${i}Version%%.*}\""
done

PROVIDES="
	ffmpeg$secondaryArchSuffix = $portVersionCompat
	lib:libavcodec$secondaryArchSuffix = $libavcodecVersionCompat
	lib:libavfilter$secondaryArchSuffix = $libavfilterVersionCompat
	lib:libavformat$secondaryArchSuffix = $libavformatVersionCompat
	lib:libavutil$secondaryArchSuffix = $libavutilVersionCompat
	lib:libswresample$secondaryArchSuffix = $libswresampleVersionCompat
	lib:libswscale$secondaryArchSuffix = $libswscaleVersionCompat
	"
REQUIRES="
	haiku$secondaryArchSuffix
	lib:libbz2$secondaryArchSuffix
	lib:libmp3lame$secondaryArchSuffix
	lib:libogg$secondaryArchSuffix
	lib:libspeex$secondaryArchSuffix
	lib:libssl$secondaryArchSuffix
	lib:libtheoradec$secondaryArchSuffix
	lib:libtheoraenc$secondaryArchSuffix
	lib:libvorbis$secondaryArchSuffix
	lib:libvorbisenc$secondaryArchSuffix
	lib:libz$secondaryArchSuffix
	"
if [ "$effectiveTargetArchitecture" != x86_gcc2 ]; then
	REQUIRES+="
		lib:libopenmpt$secondaryArchSuffix
		lib:libvpx$secondaryArchSuffix
		"
fi
CONFLICTS="
	ffmpeg_legacy$secondaryArchSuffix
	ffmpeg${secondaryArchSuffix}_bin
	ffmpeg2${secondaryArchSuffix}_bin
	"

PROVIDES_avdevice="
	ffmpeg${secondaryArchSuffix}_avdevice = $portVersionCompat
	lib:libavdevice$secondaryArchSuffix = $libavdeviceVersionCompat
	"
REQUIRES_avdevice="
	haiku$secondaryArchSuffix
	lib:libavcodec$secondaryArchSuffix == $libavcodecVersion
	lib:libavfilter$secondaryArchSuffix == $libavfilterVersion
	lib:libavformat$secondaryArchSuffix == $libavformatVersion
	lib:libavutil$secondaryArchSuffix == $libavutilVersion
	lib:libSDL2_2.0$secondaryArchSuffix
	"

PROVIDES_tools="
	ffmpeg${secondaryArchSuffix}_tools = $portVersion
	cmd:ffmpeg = $portVersionCompat
	cmd:ffplay = $portVersionCompat
	cmd:ffprobe = $portVersionCompat
	"
REQUIRES_tools="
	haiku$secondaryArchSuffix
	lib:libavcodec$secondaryArchSuffix == $libavcodecVersion
	lib:libavdevice$secondaryArchSuffix == $libavdeviceVersion
	lib:libavfilter$secondaryArchSuffix == $libavfilterVersion
	lib:libavformat$secondaryArchSuffix == $libavformatVersion
	lib:libavutil$secondaryArchSuffix == $libavutilVersion
	lib:libSDL2_2.0$secondaryArchSuffix
	"

PROVIDES_devel="
	ffmpeg${secondaryArchSuffix}_devel = $portVersionCompat
	devel:libavcodec$secondaryArchSuffix = $libavcodecVersionCompat
	devel:libavdevice$secondaryArchSuffix = $libavdeviceVersionCompat
	devel:libavfilter$secondaryArchSuffix = $libavfilterVersionCompat
	devel:libavformat$secondaryArchSuffix = $libavformatVersionCompat
	devel:libavutil$secondaryArchSuffix = $libavutilVersionCompat
	devel:libswresample$secondaryArchSuffix = $libswresampleVersionCompat
	devel:libswscale$secondaryArchSuffix = $libswscaleVersionCompat
	"
REQUIRES_devel="
	ffmpeg$secondaryArchSuffix == $portVersion base
	ffmpeg${secondaryArchSuffix}_avdevice == $portVersion
	devel:libspeex$secondaryArchSuffix
	"
CONFLICTS_devel="
	ffmpeg_legacy${secondaryArchSuffix}_devel
	ffmpeg${secondaryArchSuffix}_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:libmp3lame$secondaryArchSuffix
	devel:libogg$secondaryArchSuffix
	devel:libsdl2$secondaryArchSuffix
	devel:libspeex$secondaryArchSuffix
	devel:libssl$secondaryArchSuffix
	devel:libtheora$secondaryArchSuffix
	devel:libvorbis$secondaryArchSuffix
	devel:libz$secondaryArchSuffix
	"
if [ "$effectiveTargetArchitecture" != x86_gcc2 ]; then
	BUILD_REQUIRES+="
		devel:libopenmpt$secondaryArchSuffix
		devel:libvpx$secondaryArchSuffix
		"
fi
BUILD_PREREQUIRES="
	cmd:awk
	cmd:cmp
	cmd:gcc$gccSuffix >= 7
	cmd:g++$secondaryArchSuffix
	cmd:ld$gccSuffix
	cmd:grep
	cmd:make
	cmd:perl
	cmd:pkg_config$secondaryArchSuffix
	cmd:sed
	cmd:texi2html
	cmd:yasm
	"

PATCH()
{
	# patch hard-coded paths to perl
	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 ffmpeg$secondaryArchSuffix \
	$libDir/libavcodec.so.$libavcodecVersion \
	$libDir/libavfilter.so.$libavfilterVersion \
	$libDir/libavformat.so.$libavformatVersion \
	$libDir/libavutil.so.$libavutilVersion \
	$libDir/libswresample.so.$libswresampleVersion \
	$libDir/libswscale.so.$libswscaleVersion \
	"$(getPackagePrefix avdevice)/$relativeLibDir"/libavdevice.so.$libavdeviceVersion \
	"$(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-libopenmpt"
	fi

	# not an autotools configure
	./configure \
		$ccArgs \
		--prefix=$prefix \
		--bindir=$binDir \
		--datadir=$dataDir/$portName \
		--incdir=$includeDir \
		--libdir=$libDir \
		--shlibdir=$libDir \
		--mandir=$manDir \
		--disable-debug \
		--disable-stripping \
		--disable-static \
		--enable-shared \
		--enable-version3 \
		--enable-openssl \
		--enable-libvorbis \
		--enable-libspeex \
		--enable-libtheora \
		--enable-libmp3lame \
		$extraArgs

	make $jobArgs
}

INSTALL()
{
	make install

	prepareInstalledDevelLibs $ffmpegLibs
	fixPkgconfig

	# The pkgconfig file reference other libraries using the wrong paths, which
	# creates a lot of confusion. Fix them so correct paths are used.
	local develPackageName="${portName}_devel-$portFullVersion"
	local packageLinksDir=$(dirname $portPackageLinksDir)
	local linksDir="$packageLinksDir/${develPackageName}/devel~libspeex$secondaryArchSuffix/$relativeDevelopLibDir"
	sed -i -e "s,^\(Libs.private.*\)-L.*speex.* \(-lspeex.*\),\1-L$linksDir \2," \
		$developLibDir/pkgconfig/libavcodec.pc \
		$developLibDir/pkgconfig/libavdevice.pc \
		$developLibDir/pkgconfig/libavfilter.pc \
		$developLibDir/pkgconfig/libavformat.pc

	# Move html docs to the right place.
	mkdir -p $docDir
	mv $prefix/share/doc/ffmpeg $docDir
	rm -r $prefix/share

	# Split out libs and executables which need libSDL
	packageEntries tools $binDir
	packageEntries avdevice $libDir/libavdevice*

	# devel package
	packageEntries devel \
		$dataDir/ffmpeg$secondaryArchSuffix/examples \
		$manDir/man3 \
		$docDir \
		$developDir
}

TEST()
{
	make check
}
