#!/bin/bash

# mpeg2vpx ke 3.6.2015 20.23.46 +0300a
#   - --tile-columns=6, --frame-parallel=1
#   - overridable vpxenc
#
# ma 6.1.2014 16.32.57 +0200
#	- the name at the top of this log, oops
#	- vp8/vp9
#
# ti 25.6.2013 16.37.53 +0300
#	- trap Ctrl-C
#
# ma 24.6.2013 15.15.58 +0300
#	- allow --arnr-(maxframes|strength) be set
#	  via ARNR_MAXFRAMES and ARNR_STRENGTH
#
# la 22.6.2013 16.11.56 +0300
#	- echo crucial commands even when not dry-run
#	- use -ss when SEEK set
#	- optional CROP_FIRST for weird crop-first material
#	- allow --(min|max)-q be set via MIN_Q and MAX_Q
#
# ke 19.6.2013 21.43.17 +0300
#	- output size "0M" when dry run
#	- other filters
#	- cropped dimensions = final dimensions, duh
#
# ke 19.6.2013 20.15.30 +0300

SELF=`basename "$0"`
if [ $# -lt 1 ]
then
  echo "usage: $SELF basename[.sh]"
  exit 1
fi

VPX=vp8
if [ "${SELF:(-3)}" == "vp9" ]
then
  VPX=vp9
fi

# user vpxenc from $PATH by default (override in $1.sh)
VPXENC=vpxenc

# function called by trap
stop_on_ctrl_c() {
  exit 1
}
trap 'stop_on_ctrl_c' 2

for BASENAME_READABLE in "$1" "$1.sh"
do
  if [ -r "$BASENAME_READABLE" ]
  then
    BASENAME=${BASENAME_READABLE}
  fi
done

if [ -z "${BASENAME}" ]
then
  echo "$1[.sh] unreadable."
  exit 1
fi

. "${BASENAME}"
BASENAME="${BASENAME%%.sh}"

echo BASENAME = $BASENAME
while read SETTING
do
  if [ -z "${!SETTING}" ]
  then
    echo "${SETTING} has not been set."
    exit 1
  fi
  echo $SETTING = ${!SETTING}
done < <(cat << EOM
TARGET_QUALITY
MAXIMUM_BITRATE
AUDIO_QUALITY
SCALED_WIDTH
SCALED_HEIGHT
CROPPED_WIDTH
CROPPED_HEIGHT
CROPPING_LEFT
CROPPING_TOP
DEINTERLACER
OUTPUT_FPS
EOM
)

[ "${THREADS:+set}" != set ] && THREADS=1
[ "${MIN_Q:+set}" != set ] && MIN_Q=0
[ "${MAX_Q:+set}" != set ] && MAX_Q=63
[ "${ARNR_MAXFRAMES:+set}" != set ] && ARNR_MAXFRAMES=7
[ "${ARNR_STRENGTH:+set}" != set ] && ARNR_STRENGTH=5
[ "${SEEK:+set}" == set ] && SS=-ss
[ "${DURATION:+set}" == set ] && TT=-t

DOING_DRY_RUN=false
NOT_DOING_DRY_RUN=true
if [ "${DRY_RUN:+set}" == set ]
then
  DOING_DRY_RUN=true
  NOT_DOING_DRY_RUN=false
fi

# static build 2013-06-14 of ffmpeg works.
FFMPEG=/usr/local/bin/ffmpeg

# audio
for DO in echo ""
do 
  if [ "${DO}" != "echo" ] && $DOING_DRY_RUN ; then break ; fi

  $DO avconv -y -i \
   "${BASENAME}.mpeg" \
   ${SS} ${SEEK} \
   ${TT} ${DURATION} \
   -c:a libvorbis \
   -q:a ${AUDIO_QUALITY} \
   -sn -vn \
   "${BASENAME}-audio.ogg"
done

function set_up_crop {
  FILTERS=${FILTERS},crop=${CROPPED_WIDTH}:${CROPPED_HEIGHT}:${CROPPING_LEFT}:${CROPPING_TOP}
}
function set_up_scale {
  FILTERS=${FILTERS},scale=${SCALED_WIDTH}:${SCALED_HEIGHT}
}

# filtered raw video
FILTERS=null
FILTERS=${FILTERS},${DEINTERLACER}
if [ "${CROP_FIRST:+set}" == set ]
then
  set_up_crop
  set_up_scale
  FINAL_HEIGHT=${SCALED_HEIGHT}
  FINAL_WIDTH=${SCALED_WIDTH}
else
  set_up_scale
  set_up_crop
  FINAL_HEIGHT=${CROPPED_HEIGHT}
  FINAL_WIDTH=${CROPPED_WIDTH}
fi
FILTERS=${FILTERS},${UNSHARP}
FILTERS=${FILTERS},${GRAY}
FILTERS=${FILTERS},${OTHER}

for DO in echo ""
do 
  if [ "${DO}" != "echo" ] && $DOING_DRY_RUN ; then break ; fi

  $DO avconv -y -i \
   "${BASENAME}.mpeg" \
   ${SS} ${SEEK} \
   ${TT} ${DURATION} \
   -vf ${FILTERS} \
   -r ${OUTPUT_FPS} \
   -f yuv4mpegpipe \
   -pix_fmt yuv420p \
   -an -sn \
   "${BASENAME}.y4m" 
done

# video encoding: tune --target-bitrate
for PASS in 1 2
do
  for DO in echo ""
  do 
    if [ "${DO}" != "echo" ] && $DOING_DRY_RUN ; then break ; fi

    $DO $VPXENC \
     -w ${FINAL_WIDTH} -h ${FINAL_HEIGHT} \
     --codec=$VPX --good --cpu-used=4 \
     --target-bitrate=${MAXIMUM_BITRATE} \
     --end-usage=cq --min-q=${MIN_Q} --cq-level=${TARGET_QUALITY} --max-q=${MAX_Q} \
     --passes=2 --fpf="${BASENAME}.log" --pass=$PASS \
     --threads=${THREADS} \
     --auto-alt-ref=1 --lag-in-frames=16 \
     --tile-columns=6 --frame-parallel=1 \
     --arnr-maxframes=${ARNR_MAXFRAMES} --arnr-strength=${ARNR_STRENGTH} \
     -o "${BASENAME}-video.webm" \
     "${BASENAME}.y4m"
  done
done


# muxing
for DO in echo ""
do 
  if [ "${DO}" != "echo" ] && $DOING_DRY_RUN ; then break ; fi

  $DO $FFMPEG \
   -i "${BASENAME}-video.webm" \
   -i "${BASENAME}-audio.ogg" \
   -c:v copy -c:a copy \
   "${BASENAME}.webm"
done

OUTPUT_SIZE=`$NOT_DOING_DRY_RUN && du --si "${BASENAME}.webm" | cut -f 1 || echo 0M`
echo "finished. output ${BASENAME}.webm, $OUTPUT_SIZE"
