#!/bin/sh
#
#	$Id: image2mpeg 1092 2007-09-15 10:41:00Z gromeck $
#
#	Copyright (c) 2004 by Christian Lorenz
#

#
#	load the common functions
#
for DIR in . $( dirname $0 )/../lib/image2mpeg /usr/lib/image2mpeg /usr/local/lib/image2mpeg; do
	if [ -e $DIR/commonfuncs.sh ]; then
		. $DIR/commonfuncs.sh
		break
	fi
done

VERBOSE=0
NOP=0
FORMAT=0
SAMPLERATE=0
VIDEO_BUFFER=0
BITRATE=0
BITRATE_VIDEO=0
BITRATE_AUDIO=0
BITRATE_SPARE=0
AUDIO_CODEC="mp2"
WIDTH=0
HEIGHT=0
NORM="p"
NORMLONG="pal"
FPS=0
TIMEPERPHOTO=5
TIMEPERTRANSITION=1.6
QUANTISATION=5
MOTION_SEARCH_RADIUS=16
TRANSITION=random
QUICKMODE=""
KENBURNS=""
ASPECTRATIO="4:3"
ASPECTCORRECTION="auto"
SCROLLMODE=""
GIPS=""
IMGS=""
MP3S=""
OUTPUT=""
INDEX=""
AUDIOENCODER=FFMPEG
VIDEOENCODER=FFMPEG
THREADS=$( cat /proc/cpuinfo 2>/dev/null | grep -c ^processor )


################################################################################
#
#	show the usage
#
show_usage()
{
	[ "$*" != "" ] && echo "$*"
cat <<-EOM
Usage: $0 [options] ( [ ( <JPEG file> | <MP3 file>) ... ] | '@' <gip index file> )
Options are:
    -?
    --help                     Show this message and exit.
    -V
    --version                  Show version and exit.
    -v <level>
    --verbose <level>          Increase verosity.
    --nop                      Don't execute any commands;
                               just print what would be executed
    -E <str>
    --audio-encoder <str>      Select the audio encoder to use (LAME, TOOLAME, FFMPEG)
    -e <str>
    --encoder <str>
    --video-encoder <str>      Select the video encoder to use (MPEG2ENC, FFMPEG)
    -q
    --quick                    Run in quick mode (= pore quality)
    -k
    --kenburns                 Force Ken-Burns-Effect
    --aspect <ar>
    --aspect-ratio <ar>        Set the aspect ratio (4:3 or 16:9)
    -A
    --aspect-correction <mode> Set the aspect correction mode (AUTO, NONE, FITIN, FILLIN)         
    -m <str>
    --mode <str>               Type of output (VCD, SVCD, DVD)
    -n <str>
    --norm <str>               Video norm (p=pal, n=ntsc)
    -w <n>
    --width <width>            Width of output (to override the width
                               according to the selected mode)
    -h <n>
    --height <width>           Height of output (to override the height
                               according to the selected mode)
    -b <n>
    --bitrate <n>              Bitrate (to override the bitrate according
                               to the selected mode)
    -a <n>
    --audio-bitrate <n>        Audio bitrate (to override the audio
                               bitrate according to the selected mode)
    --audio-codec <codec>      Audio codec to use (mp2, ac3)
    -s 
    --scroll                   enable the scroll mode (instead of scaling
                               down images with a non fitting aspect ratio,
                               they will be scrolled thru the screen). This
                               feature is also used for creating credits.
    -t
    --time-per-image <n>       Time per image
    -T
    --time-per-transition <n>  Time per transition
    --transition <str>         Transition mode (random, fade)
    -o <str>
    --output <str>             Output file
    -I <str>
    --index <str>              Write an GIP index file 
EOM
	[ "$*" != "" ] && exit 1
	exit 0
}


################################################################################
#
#	check the arguments
#
while [ "$1" != "" ]; do
	if [ "$( echo "#$1" | cut -c2 )" = '-' ]; then
		case "$1" in
			-\?|--help)
				#
				#	show the usage
				#
				show_usage
				exit 0
				;;
			-V|--version)
				#
				#	show the version
				#
				echo '$Id: image2mpeg 1092 2007-09-15 10:41:00Z gromeck $'
				exit 0
				;;
			-v|--verbose)
				#
				#	verbosity level
				#
				shift
				VERBOSE=$1
				;;
			--nop)
				#
				#	don't do something just print the commands to execute
				#
				NOP=1
				;;
			-E|--audio-encoder)
				#
				#	select the audio encoder
				#
				shift
				case "$1" in
					lame|LAME)
						#
						#	use lame
						#
						AUDIOENCODER=LAME
						;;
					toolame|TOOLAME)
						#
						#	use toolame
						#
						AUDIOENCODER=TOOLAME
						;;
					ffmpeg|FFMPEG)
						#
						#	use ffmpeg
						#
						AUDIOENCODER=FFMPEG
						;;
					*)
						show_usage "Unknown audio encoder '$1'"
				esac
				;;
			-e|--encoder|--video-encoder)
				#
				#	select the video encoder
				#
				shift
				case "$1" in
					mpeg2enc|MPEG2ENC)
						#
						#	use mpeg2enc
						#
						VIDEOENCODER=MPEG2ENC
						;;
					ffmpeg|FFMPEG)
						#
						#	use ffmpeg
						#
						VIDEOENCODER=FFMPEG
						;;
					*)
						show_usage "Unknown video encoder '$1'"
				esac
				;;
			-m|--mode)
				#
				#	mode of output
				#
				shift
				MODE="$1"
				;;
			-n|--norm|--video-norm)
				#
				#	video norm
				#
				shift
				case "$1" in
					p|P|pal|PAL)
						#
						#	PAL
						#
						NORM=p
						NORMLONG=pal
						;;
					n|N|ntsc|NTSC)
						#
						#	NTSC
						#
						NORM=n
						NORMLONG=ntsc
						;;
					*)
						show_usage "Unknown video norm '$1'"
				esac
				;;
			-w|--width)
				#
				#	width
				#
				shift
				WIDTH=$1
				;;
			-h|--height)
				#
				#	height
				#
				shift
				HEIGHT=$1
				;;
			-q|--quick)
				#
				#	quick mode
				#
				QUICKMODE="--quick"
				;;
			-k|--kenburns)
				#
				#	force Ken-Burns-Effect
				#
				KENBURNS="--kenburns"
				;;
			--aspect|--aspect-ratio)
				#
				#	aspect ratio
				#
				shift
				case "$1" in
					4:3)
						#
						#	4:3
						#
						ASPECTRATIO=4:3
						;;
					16:9)
						#
						#	16:9
						#
						ASPECTRATIO=16:9
						;;
					*)
						show_usage "Unknown aspect ratio norm '$1'"
				esac
				;;
			-A|--aspect-correction)
				#
				#	set the aspect correction mode
				#
				shift
				ASPECTCORRECTION=$1
				;;
			-s|--scroll)
				#
				#	scroll mode
				#
				SCROLLMODE="--scroll"
				;;
			-t|--time-per-photo|--time-per-image)
				shift
				TIMEPERPHOTO=$1
				;;
			-T|--time-per-transition)
				shift
				TIMEPERTRANSITION=$1
				;;
			--transition)
				shift
				TRANSITION=$1
				;;
			-b|--bitrate)
				shift
				BITRATE=$1
				;;
			-a|--audio-bitrate)
				shift
				BITRATE_AUDIO=$1
				;;
			--audio-codec)
				shift
				AUDIO_CODEC=$1
				;;
			-o|--output)
				#
				#	output file
				#
				shift
				OUTPUT=$1
				;;
			-I|--index)
				#
				#	index file
				#
				shift
				INDEX="$1"
				;;
			*)
				#
				#	unknown option
				#
				show_usage "Unknown option '$1'"
				exit 1
				;;
		esac
	else
		#
		#	check the given files
		#
		if [ "$( echo "$1" | cut -c1 )" = "@" ]; then
			GIPS="$GIPS $1"
		else
			[ ! -r "$1" ] && die "Couldn't read '$1'"
			EXT=$( echo "$1" | sed -e "s/^.*\.//" )
#echo EXT=$EXT
			case "$EXT" in
				jpg|JPG|jpeg|JPEG|png|PNG)
					IMGS="$IMGS '$1'"
					;;
				mp3|MP3)
					MP3S="$MP3S '$1'"
					;;
				*)
					die "Unknown file type '$FILE'"
			esac
		fi
	fi
	shift
done

#
#	if we got an GIP index, we will extract the audio files from
#	this index
#
if [ "$GIPS" != "" ]; then
	[ "$JPGS" != "" ] && echo "Ignoring given JPG files"
	JPGS=""
	[ "$MP3S" != "" ] && echo "Ignoring given MP3 files"
	MP3S=""
	FILES="$GIPS"
	for GIP in $GIPS; do
		GIP="$( echo "$GIP" | cut -c2- )"
		[ "$MP3S" != "" ] && MP3S="$MP3S "
		MP3S="$MP3S$( grep -i "^type=AUDIO" "$GIP" | \
						sed -e "s/,/\n/g" | \
						grep -i "^file=" | \
						cut -f2 -d= | \
						while read MP3; do echo -n "'$MP3' "; done )"
	done
	echo "Extracted MP3 files from $GIPS"
else
	FILES="$MP3S $IMGS"
fi

read FORMAT FPS WIDTH HEIGHT BITRATE BITRATE_AUDIO SAMPLERATE VIDEO_BUFFER <<EOM
	$( getvideoformat "$MODE" "$NORM" "$FPS" "$WIDTH" "$HEIGHT" "$BITRATE" "$BITRATE_AUDIO" "$SAMPLERATE" "$VIDEO_BUFFER" )
EOM
#echo "VERBOSE=$VERBOSE"
#echo "QUICKMODE=$QUICKMODE"
#echo "KENBURNS=$KENBURNS"
#echo "> MODE=$MODE"
#echo "> NORM=$NORM"
#echo "< FORMAT=$FORMAT"
#echo "< FPS=$FPS"
#echo "< WIDTH=$WIDTH"
#echo "< HEIGHT=$HEIGHT"
#echo "< BITRATE=$BITRATE"
#echo "< BITRATE_AUDIO=$BITRATE_AUDIO"
#echo "< SAMPLERATE=$SAMPLERATE"
#echo "< VIDEO_BUFFER=$VIDEO_BUFFER"
#echo "OUTPUT=$OUTPUT"
#echo "INDEX=$INDEX"
#exit

################################################################################
#
#	check the given arguments
#
[ "$MODE" = "" ] && die "Sorry, 'mode' is not set!"
[ "$WIDTH" = 0 ] && die "Sorry, 'width' is not set!"
[ "$HEIGHT" = 0 ] && die "Sorry, 'height' is not set!"
[ "$FILES" = "" ] && die "Sorry, no input files given!"
[ "$OUTPUT" = "" ] && [ "$INDEX" = "" ] && die "Sorry, no output file specified!"


################################################################################
#
#	compute the bitrate stuff
#
if [ $VIDEOENCODER = MPEG2ENC ]; then
	#
	#	so, we will use mplex, which needs a little
	#	bit spare
	#
	BITRATE_SPARE=$( echo "scale=0; $BITRATE * 0.02/1" | bc )
fi
BITRATE_VIDEO=$(( $BITRATE - $BITRATE_AUDIO - $BITRATE_SPARE ))
echo "$( basename $0 ): Video Bitrate: ${BITRATE_VIDEO}kbps"
echo "$( basename $0 ): Audio Bitrate: ${BITRATE_AUDIO}kbps"
echo "$( basename $0 ): Spare Bitrate: ${BITRATE_SPARE}kbps"
echo "$( basename $0 ): Total Bitrate: ${BITRATE}kbps"


################################################################################
#
#	setup temporary files
#
TMP="/tmp/"
TMP_FILE="$TMP/$( basename $0 )-$$"
VIDEO_TMP=$TMP_FILE.m1v
AUDIO_TMP=$TMP_FILE.$AUDIO_CODEC
LOGFILE="$OUTPUT.log"
rm -f $LOGFILE


################################################################################
#
#	install a cleanup handler
#
cleanup()
{
	echo "Cleaning up."
	rm -f $VIDEO_TMP $AUDIO_TMP
}
trap cleanup EXIT


if [ "$INDEX" != "" ]; then
	################################################################################
	#
	#	generate an index file
	#
	IMAGE2PPM="image2ppm -v $VERBOSE \
			--video-norm $NORM \
			--format $FORMAT \
			--width $WIDTH \
			--height $HEIGHT \
			$QUICKMODE \
			$KENBURNS \
			$SCROLLMODE \
			--aspect-ratio $ASPECTRATIO \
			--aspect-correction $ASPECTCORRECTION \
			--time-per-photo $TIMEPERPHOTO \
			--time-per-transition $TIMEPERTRANSITION \
			--transition $TRANSITION \
			--index $INDEX \
			$FILES"
	if [ $NOP != 0 ]; then
		echo $IMAGE2PPM
	else
		echo $IMAGE2PPM >>$LOGFILE
		nicerun "$IMAGE2PPM"
	fi
	exit 0
fi


################################################################################
#
#	we have to do some probes
#
SAMPLERATEK="$( echo "scale=3; $SAMPLERATE / 1000" | bc -l )"
LAME_SAMPLERATE="$SAMPLERATEK"
if [ $( probe_toolame_srate_hz toolame ) != 0 ]; then
	TOOLAME_SAMPLERATE="$SAMPLERATE"
else
	TOOLAME_SAMPLERATE="$SAMPLERATEK"
fi
if [ $( probe_ppmtoy4m_420mpeg2 ppmtoy4m ) != 0 ]; then
	PPMTOY4M_SUBSAMPLEMODE="420mpeg2"
else
	PPMTOY4M_SUBSAMPLEMODE="420_mpeg2"
fi


################################################################################
#
#	generate the audio stream
#
if [ "$MP3S" != "" ]; then
	case $AUDIOENCODER in
		LAME)
			################################################################################
			#
			#	LAME version
			#
			ENCODE="madplay \
					--quiet \
					--adjust-volume=-2 \
					--sample-rate=$SAMPLERATE \
					-o wave:- \
					$MP3S | \
				lame \
					-b $BITRATE_AUDIO \
					-s $LAME_SAMPLERATE \
					/dev/stdin $AUDIO_TMP"
			;;
		TOOLAME)
			################################################################################
			#
			#	TOOLAME version
			#
			ENCODE="madplay \
					--quiet \
					--adjust-volume=-2 \
					--sample-rate=$SAMPLERATE \
					-o wave:- \
					$MP3S | \
				toolame \
					-b $BITRATE_AUDIO \
					-s $TOOLAME_SAMPLERATE \
					/dev/stdin $AUDIO_TMP"
			;;
		FFMPEG)
			################################################################################
			#
			#	FFMPEG version
			#
			ENCODE="madplay \
					--quiet \
					--adjust-volume=-2 \
					--sample-rate=$SAMPLERATE \
					-o wave:- \
					$MP3S | \
				ffmpeg -y -er 2 \
					-i - \
					-acodec $AUDIO_CODEC \
					-ar $SAMPLERATE \
					-ab ${BITRATE_AUDIO}k \
					$AUDIO_TMP"
			;;
		*)
			show_usage "Unknown audio encoder '$AUDIOENCODER'"
	esac
	if [ $NOP != 0 ]; then
		echo $ENCODE
	else
		echo $ENCODE >>$LOGFILE
		nicerun "$ENCODE"
	fi
else
	AUDIO_TMP=""
fi

case $VIDEOENCODER in
	MPEG2ENC)
		################################################################################
		#
		#	MJPEGTOOLS version
		#
		#	generate video stream
		#
		ENCODE="image2ppm -v $VERBOSE \
				--threads $THREADS \
				--video-norm $NORM \
				--format $FORMAT \
				--width $WIDTH \
				--height $HEIGHT \
				$QUICKMODE \
				$KENBURNS \
				$SCROLLMODE \
				--aspect-ratio $ASPECTRATIO \
				--aspect-correction $ASPECTCORRECTION \
				--time-per-photo $TIMEPERPHOTO \
				--time-per-transition $TIMEPERTRANSITION \
				--transition $TRANSITION \
				--output - \
				$FILES | \
			ppmtoy4m -v $VERBOSE \
				-F $FPS \
				-S $PPMTOY4M_SUBSAMPLEMODE | \
			mpeg2enc -v $VERBOSE \
				--format $FORMAT \
				--aspect $( if [ "$ASPECTRATIO" = "4:3" ]; then echo 2 ; else echo 3; fi ) \
				--video-norm $NORM \
				--video-bitrate $BITRATE_VIDEO \
				--nonvideo-bitrate $BITRATE_AUDIO \
				--video-buffer $VIDEO_BUFFER \
				--quantisation $QUANTISATION \
				--motion-search-radius $MOTION_SEARCH_RADIUS \
				-o $VIDEO_TMP"
		if [ $NOP != 0 ]; then
			echo $ENCODE
		else
			echo $ENCODE >>$LOGFILE
			nicerun "$ENCODE"
		fi


		################################################################################
		#
		#	multiplex video and audio together
		#
		MPLEX="mplex -v 1 \
			-f $FORMAT \
			-o $OUTPUT \
			--video-buffer $VIDEO_BUFFER \
			--mux-bitrate $BITRATE \
			$VIDEO_TMP $AUDIO_TMP"
		if [ $NOP != 0 ]; then
			echo $MPLEX
		else
			echo $MPLEX >>$LOGFILE
			nicerun "$MPLEX"
		fi
		;;
	FFMPEG)
		################################################################################
		#
		#	FFMPEG version
		#
		#	generate video stream
		#
		ENCODE="image2ppm -v $VERBOSE \
				--threads $THREADS \
				--video-norm $NORM \
				--format $FORMAT \
				--width $WIDTH \
				--height $HEIGHT \
				$QUICKMODE \
				$KENBURNS \
				$SCROLLMODE \
				--aspect-ratio $ASPECTRATIO \
				--aspect-correction $ASPECTCORRECTION \
				--time-per-photo $TIMEPERPHOTO \
				--time-per-transition $TIMEPERTRANSITION \
				--transition $TRANSITION \
				--output - \
				$FILES | \
			ffmpeg -y -er 2 \
				-f image2pipe \
				-vcodec ppm \
				-r $FPS \
				-i - \
				$( [ "$AUDIO_TMP" ] && echo "-i $AUDIO_TMP" ) \
				-tvstd $NORMLONG \
				-target $( echo "$NORMLONG-$MODE" | tr "[:upper:]" "[:lower:]" ) \
				-s ${WIDTH}x${HEIGHT} \
				-aspect $ASPECTRATIO \
				-b ${BITRATE_VIDEO}k \
				-acodec $AUDIO_CODEC \
				-ar $SAMPLERATE \
				-ab ${BITRATE_AUDIO}k \
				$OUTPUT"
		if [ $NOP != 0 ]; then
			echo $ENCODE
		else
			echo $ENCODE >>$LOGFILE
			nicerun "$ENCODE"
		fi
		;;
	*)
		show_usage "Unknown video encoder '$VIDEOENCODER'"
esac

#
#	EOF
#
