#!/bin/bash
################################################################################
#
# Copyright (c) 2015-2019, NVIDIA CORPORATION. All rights reserved.
#
# NVIDIA Corporation and its licensors retain all intellectual property
# and proprietary rights in and to this software, related documentation
# and any modifications thereto. Any use, reproduction, disclosure or
# distribution of this software and related documentation without an express
# license agreement from NVIDIA Corporation is strictly prohibited.
#
################################################################################

function throw_error {
	local ERROR=$1
	echo -e "\n**ERROR** $ERROR. Exiting...\n"
	exit 1
}

VERSION=1.14.0
PREFIX=/usr

ARCH=`dpkg --print-architecture`
case "$ARCH" in
	arm64)
		ABI_DIR=aarch64-linux-gnu
		;;
	*)
		throw_error "Unsupported architecture $ARCH. This script should be run only on an L4T device"
		;;
esac

dpkg -s nvidia-l4t-core &> /dev/null
if [ $? -ne 0 ] && [ ! -f "/etc/nv_tegra_release" ]; then
	throw_error "This script should be run only on an L4T device."
fi

GST_PLUGIN_DIR=/usr/lib/$ABI_DIR/gstreamer-1.0/

PACKAGES=('gstreamer')
PACKAGES+=('gst-plugins-base')
PACKAGES+=('gst-plugins-good')
PACKAGES+=('gst-plugins-bad')
PACKAGES+=('gst-plugins-ugly')
PACKAGES+=('gst-libav')

declare -A REQ_PACKAGES
REQ_PACKAGES[all]="dpkg-dev flex bison autotools-dev automake liborc-dev
		autopoint libtool gtk-doc-tools libgstreamer1.0-dev"
REQ_PACKAGES[gstreamer]=""
REQ_PACKAGES[gst-plugins-base]="libxv-dev libasound2-dev libtheora-dev
		libogg-dev libvorbis-dev"
REQ_PACKAGES[gst-plugins-good]="libbz2-dev libv4l-dev libvpx-dev
		libjack-jackd2-dev libsoup2.4-dev libpulse-dev"
REQ_PACKAGES[gst-plugins-bad]="faad libfaad-dev libfaac-dev"
REQ_PACKAGES[gst-plugins-ugly]="libx264-dev libmad0-dev "

NV_PLUGINS=(`find $GST_PLUGIN_DIR -name "libgstnv*" | awk -F '/' '{print $NF}'`)
NV_PLUGINS+=('libgstomx.so')

function build {
	local PKG=$1-$VERSION
	local FILE="$PKG.tar.xz"
	local SHAFILE=$FILE".sha256sum"

	apt-get install -y ${REQ_PACKAGES[$1]}

	rm -rf $SHAFILE $SHAFILE.1
	if [ -f $FILE ]; then
		wget --no-check-certificate "http://gstreamer.freedesktop.org/src/$1/$SHAFILE" >/dev/null 2>&1
		sha256sum $FILE > $SHAFILE.1
		diff $SHAFILE $SHAFILE.1 >/dev/null \
			|| wget --no-check-certificate "http://gstreamer.freedesktop.org/src/$1/$FILE" -O $FILE\
			|| throw_error "$PKG not found"
	else
		wget --no-check-certificate "http://gstreamer.freedesktop.org/src/$1/$FILE" \
			|| throw_error "$PKG not found"
	fi

	tar xf $FILE
	cd $PKG
	./configure --prefix=$PREFIX --libdir=$PREFIX/lib/$ABI_DIR/ \
			--libexecdir=$PREFIX/lib/$ABI_DIR/gstreamer1.0
	make -j8 || throw_error "Error building $PKG"
	make install || throw_error "Error installing $PKG in \"$PREFIX\""
	cd ..
}

for i in "$@" ; do
	case $i in
		--version=*)
			VERSION="${i#*=}"
			;;
			--prefix=*)
			PREFIX="${i#*=}"
			;;
		--help)
			echo "Script to install gstreamer from source"
			echo "Usage: $0 [--prefix=/install/path] [--version=VERSION]"
			exit 0
			;;
		*)
			echo "Error: Unknown option $i"
			echo "Usage: $0 [--prefix=/install/path] [--version=VERSION]"
			exit 1
			;;
	esac
done

[[ $EUID -eq 0 ]] || throw_error "Please run as root"

[[ -d "$PREFIX" ]] && PREFIX=`cd $PREFIX && pwd`
BACKUP_REQ=0

echo "Installing $ARCH version of Gstreamer-$VERSION in \"$PREFIX\"."
if [ -f "$PREFIX/lib/$ABI_DIR/libgstreamer-1.0.so.0" ]; then
	LINK_FILE=`readlink "$PREFIX/lib/$ABI_DIR/libgstreamer-1.0.so.0"`
	FILE_VERSION=`echo $LINK_FILE | awk -F'.' '{print $(NF -1)}'`
	INSTALLED_VERSION=1.${FILE_VERSION:0:1}.${FILE_VERSION:2:1}
	BACKUP_REQ=1
	BACKUP_FILE="$HOME/gst-$INSTALLED_VERSION-$(date +"%Y%m%d_%H%M%S").tar.gz"

	echo -n "**WARNING** Gstreamer-$INSTALLED_VERSION found in \"$PREFIX\"."
	echo -n " This will get overwritten if you continue. A backup will be created"
	echo -e " in \"$BACKUP_FILE\"\n"
	echo "To recover this version:"
	echo "sudo rm -rf $PREFIX/lib/$ABI_DIR/gstreamer-1.0"
	echo -e "sudo tar xPf $BACKUP_FILE\n"
fi

while [ 1 ]; do
	read -p "Continue?[Y/n]" -n 1 -r
	echo
	[[ $REPLY =~ ^[Yy]$ ]] && break
	[[ $REPLY =~ ^[Nn]$ ]] && exit 0
done

echo -e "\n\n*** Following Packages are required for building gstreamer ***"
echo -e "\nPackages required for all:"
echo ${REQ_PACKAGES[all]}
for pkg in "${PACKAGES[@]}" ; do
	echo -e "\nPackages required for $pkg:"
	echo ${REQ_PACKAGES[$pkg]}
done

echo -e "\nThese packages will be installed automatically by the script."
while [ 1 ]; do
	read -p "Continue?[Y/n]" -n 1 -r
	echo
	[[ $REPLY =~ ^[Yy]$ ]] && break
	[[ $REPLY =~ ^[Nn]$ ]] && exit 0
done

if [ $BACKUP_REQ -eq 1 ]; then
	tar -I pigz --ignore-failed-read -P -cf "$BACKUP_FILE" \
		$PREFIX/lib/$ABI_DIR/libgst* \
		$PREFIX/bin/gst* \
		$PREFIX/lib/$ABI_DIR/gstreamer-1.0 \
		$PREFIX/include/gstreamer-1.0 \
		$PREFIX/lib/$ABI_DIR/pkgconfig/gstreamer* \
		$PREFIX/lib/$ABI_DIR/gstreamer1.0
fi

mkdir -p /tmp/gstreamer-build
cd /tmp/gstreamer-build
export PKG_CONFIG_PATH=$PREFIX/lib/$ABI_DIR/pkgconfig

apt-get install -y ${REQ_PACKAGES[all]}

for pkg in "${PACKAGES[@]}" ; do
	build $pkg
done

cd $PREFIX/lib/$ABI_DIR/gstreamer-1.0
for i in "${NV_PLUGINS[@]}" ; do
	ln -sf /usr/lib/$ABI_DIR/gstreamer-1.0/$i
done

echo -e "\n*** Gstreamer-$VERSION installed successfully ***"

[[ $BACKUP_REQ -eq 1 ]] && echo -e "\nBackup tar created: $HOME/$BACKUP_FILE"

if [ "$PREFIX" != "/usr" ]; then
	echo -e "\nRun the following commands to use GStreamer-$VERSION"
	echo "export LD_LIBRARY_PATH=$PREFIX/lib/$ABI_DIR"
	echo "export PATH=$PREFIX/bin:\$PATH"
fi
