#!/usr/bin/env bash
PROFILE="high"
ID_VIDEO_FPS="$2"
# http://forum.gleitz.info/showthread.php?42376-Blu-Ray-compliant&p=411324#post411324
# http://forum.doom9.org/showthread.php?p=730001#post730001
#
# Anzahl der Makroblöcke pro Frame (mbpf):
#
# Level 1.0: mbpf <= 99
# Level 1.1/1.2/1.3/2.0: mbpf <= 396
# Level 2.1: mbpf <= 792
# Level 2.2/3.0: mbpf <= 1620
# Level 3.1: mbpf <= 3600
# Level 3.2: mbpf <= 5120
# Level 4.0/4.1/4.2: mbpf <= 8192
# Level 5.0: mbpf <= 22080
# Level 5.1: mbpf <= 36864
# MaxMBPS = max macroblocks per second
# MaxMBPS >= width*height*fps. (w&h measured in macroblocks, i.e. pixels/16 round up in each dimension)
# MaxFS = max frame size; wird in Makroblöcken (MBs) angegeben; ein Makroblock = 16x16 Pixel
# MaxFS >= width*height (in MBs)
# width <= sqrt(MaxFS*8)
# height <= sqrt(MaxFS*8)
# MaxDPB = max decoded picture buffer
# MaxDPB >= (bytes in a frame) * min(16, ref + (pyramid ? 2 : bframes ? 1 : 0))
# MaxDPB >= (bytes in a frame) * number of reference frames (for x264 number of reference frames = min(16, ref + (pyramid ? 2 : bframes ? 1 : 0))
#
# "pyramid ? 2 : bframes ? 1 : 0" entspricht:
#
# if(pyramid)
# MaxDPB >= (bytes in a frame) * min(16, ref + 2)
# else if(bframes)
# MaxDPB >= (bytes in a frame) * min(16, ref + 1)
# else
# MaxDPB >= (bytes in a frame) * ref
#
# BIAF420 = bytes in a frame (4:2:0) = (pixel width) * (pixel height) * 1.5
#
# MaxBR = max bitrate
# MaxBR >= vbv_maxrate.
# MaxCPB = max vbv buffer
# MaxCPB >= vbv_bufsize.
# MaxVmvR = max motion vetor range
# MaxVmvR >= max_mv_range.
#
# MaxMvsPer2Mb, MinLumaBiPredSize, direct_8x8_inference_flag : are not enforced by x264. The only way to ensure compliance is to disable p4x4 at level>=3.1, or at level>=3 w/ B-frames.
# MinCR : is not enforced by x264. Won't ever be an issue unless you use lossless.
# SliceRate : I don't know what this limits.
# mbpf = aufgerundet(Breite/16) * aufgerundet(Höhe/16)
if [ -z "${1}" ] ; then
echo "${0} [Auflösung] [Bildwiederholrate]"
echo "${0} 128x96 30" # SQCIF
echo "${0} 176×144 15" # QCIF
echo "${0} 176×220 15" # QCIF+
echo "${0} 320×240 20" # QVGA
echo "${0} 352×288 20" # CIF
echo "${0} 640×480 30" # VGA
echo "${0} 704×288 25" # 2CIF
echo "${0} 704×576 25" # 4CIF
echo "${0} 720x480 30" # Full D1
echo "${0} 720x576 25" # Full D1
exit 1
fi
BILDBREITE="$(echo "${1}" | tr -s ':' 'x' | awk -F'x' '{print $1}')"
BILDHOEHE="$(echo "${1}" | tr -s ':' 'x' | awk -F'x' '{print $2}')"
echo "${BILDBREITE} / ${BILDHOEHE}"
BILDBREITE="$(echo "${1}" | awk -F'x' '{printf("%u\n",($1/2))}' | awk '{printf("%u\n",($1*2))}')"
BILDHOEHE="$(echo "${1}" | awk -F'x' '{printf("%u\n",($2/2))}' | awk '{printf("%u\n",($1*2))}')"
echo "${BILDBREITE} / ${BILDHOEHE}"
#------------------------------------------------------------------------------#
# Profile: http://wapedia.mobi/de/H.264#4.
# Level: http://wapedia.mobi/de/H.264#5.
### da es "aufrunden" (ceiling) und "vergleichen" (in einem Schritt) in AWK nicht gibt
### muss ich statt dessen "runden+vergleichen" in zwei Schritten verwenden
MBREITE="$(echo "${BILDBREITE}" | awk '{printf"%.0f\n",($1/16)}')"
MBREITE="$(echo "${BILDBREITE} ${MBREITE}" | awk '{if (($1/16) > $2) $2 = $2+1 ; print $2}')"
MHOEHE="$(echo "${BILDHOEHE}" | awk '{printf"%.0f\n",($1/16)}')"
MHOEHE="$(echo "${BILDHOEHE} ${MHOEHE}" | awk '{if (($1/16) > $2) $2 = $2+1 ; print $2}')"
MaxFS="$(echo "${MBREITE} ${MHOEHE}" | awk '{print $1 * $2}')"
BHVERH="$(echo "${MBREITE} ${MHOEHE} ${MaxFS}" | awk -v verhaeltnis="gut" '{if ($1 > (sqrt($3 * 8))) verhaeltnis="schlecht" ; if ($2 > (sqrt($3 * 8))) verhaeltnis="schlecht" ; print verhaeltnis}')"
if [ "${BHVERH}" = "gut" ] ; then
echo "# Seitenverhältnis wird von AVC unterstützt."
else
echo "# Seitenverhältnis wird von AVC nicht unterstützt!"
exit 1
fi
### Bildwiederholrate ermitteln bzw. als Rechengrundlage festlegen
BPS="$(if [ -n "${ID_VIDEO_FPS}" ] ; then
echo "${ID_VIDEO_FPS}" | awk '{print $1*1}'
else
# wenn keine Bildwiederholrate angegeben ist
echo "30"
fi)"
BIAF420="$(echo "${BILDBREITE} ${BILDHOEHE}" | awk '{print $1 * $2 * 1.5}')"
MLEVEL="$(echo "${MaxFS}" | awk '{if ($1 < 36865) LEVEL=51 ; if ($1 < 22081) LEVEL=50 ; if ($1 < 8193) LEVEL=42 ; if ($1 < 5121) LEVEL=32 ; if ($1 < 3601) LEVEL=31 ; if ($1 < 1621) LEVEL=30 ; if ($1 < 793) LEVEL=21 ; if ($1 < 397) LEVEL=20 ; if ($1 < 100) LEVEL=10 ; print LEVEL}')"
PLEVEL="$(echo "${MBREITE} ${MHOEHE} ${BPS}" | awk '{print $1 * $2 * $3}' | awk '{if ($1 < 983041) LEVEL=51 ; if ($1 < 589825) LEVEL=50 ; if ($1 < 589825) LEVEL=42 ; if ($1 < 216001) LEVEL=32 ; if ($1 < 108001) LEVEL=31 ; if ($1 < 40501) LEVEL=30 ; if ($1 < 19801) LEVEL=21 ; if ($1 < 11881) LEVEL=20 ; if ($1 < 1486) LEVEL=10 ; print LEVEL}')"
MLEVEL="$(echo "${MLEVEL} ${PLEVEL}" | awk '{if ($1 > $2) LEVEL=$1 ; if ($1 == $2) LEVEL=$1 ; if ($1 < $2) LEVEL=$2 ; print LEVEL}')"
LEVEL="$(echo "${MLEVEL}" | sed 's/[0-9]$/.&/')"
### für 1000 bit/s !!!
# http://forum.doom9.org/showthread.php?t=101345
if [ "${MLEVEL}" = "10" -a "${PROFILE}" = "high" ] ; then
MaxBR="80"
MaxCPB="175"
MaxVmvR="-64,63.75" # max. Vertical MV component range
MinCR="2"
CRF="25"
elif [ "${MLEVEL}" = "20" -a "${PROFILE}" = "high" ] ; then
MaxBR="2500"
MaxCPB="2500"
MaxVmvR="-128,127.75" # max. Vertical MV component range
MinCR="2"
CRF="24"
elif [ "${MLEVEL}" = "21" -a "${PROFILE}" = "high" ] ; then
MaxBR="5000"
MaxCPB="5000"
MaxVmvR="-256,255.75" # max. Vertical MV component range
MinCR="2"
CRF="24"
elif [ "${MLEVEL}" = "30" -a "${PROFILE}" = "high" ] ; then
MaxBR="12500"
MaxCPB="12500"
MaxVmvR="-256,255.75" # max. Vertical MV component range
MinCR="2"
CRF="23"
elif [ "${MLEVEL}" = "31" -a "${PROFILE}" = "high" ] ; then
MaxBR="17500"
MaxCPB="17500"
MaxVmvR="-512,511.75" # max. Vertical MV component range
MinCR="4"
CRF="23"
elif [ "${MLEVEL}" = "32" -a "${PROFILE}" = "high" ] ; then
MaxBR="25000"
MaxCPB="25000"
MaxVmvR="-512,511.75" # max. Vertical MV component range
MinCR="4"
CRF="23"
elif [ "${MLEVEL}" = "42" -a "${PROFILE}" = "high" ] ; then
MaxBR="62500"
MaxCPB="62500"
MaxVmvR="-512,511.75" # max. Vertical MV component range
MinCR="2"
CRF="22"
elif [ "${MLEVEL}" = "50" -a "${PROFILE}" = "high" ] ; then
MaxBR="168750"
MaxCPB="168750"
MaxVmvR="-512,511.75" # max. Vertical MV component range
MinCR="2"
CRF="21"
elif [ "${MLEVEL}" = "51" -a "${PROFILE}" = "high" ] ; then
MaxBR="300000"
MaxCPB="300000"
MaxVmvR="-512,511.75" # max. Vertical MV component range
MinCR="2"
CRF="20"
fi
### hier muss noch eine NTSC-Erkennung rein, z.B. durch die Bildwiederholfrequenz
### solange deaktiviere ich die NTSC-Möglichkeit, denn in 99% aller Fälle transcodiere ich PAL-Material
#if [ "${BILDHOEHE}" -le "480" ] ; then
# ZEILEN="480"
# FORMAT="NTSC"
# FARBCOD="smpte170m"
# SAR="10:11"
#el
if [ "${BILDHOEHE}" -le "576" ] ; then
ZEILEN="576"
FORMAT="PAL"
FARBCOD="bt470bg"
SAR="12:11"
elif [ "${BILDHOEHE}" -le "720" ] ; then
ZEILEN="720"
FORMAT="HD"
FARBCOD="bt709"
SAR="1:1"
elif [ "${BILDHOEHE}" -le "1080" ] ; then
ZEILEN="1080"
FORMAT="HD"
FARBCOD="bt709"
SAR="1:1"
fi
if [ "${MLEVEL}" = "41" ] ; then
SLICES="4"
else
SLICES="1"
fi
MREFF=""
if [ "${ZEILEN}" = "1080" ] ; then
MREFF="--ref 4"
elif [ "${ZEILEN}" = "720" -o "${ZEILEN}" = "480" ] ; then
MREFF="--ref 6"
elif [ "${ZEILEN}" = "576" -a "${MLEVEL}" -gt "30" ] ; then
MREFF="--ref 6"
elif [ "${ZEILEN}" = "576" -a "${MLEVEL}" = "30" ] ; then
MREFF="--ref 5"
fi
# if(pyramid)
# MaxDPB >= (bytes in a frame) * min(16, ref + 2)
# else if(bframes)
# MaxDPB >= (bytes in a frame) * min(16, ref + 1)
# else
# MaxDPB >= (bytes in a frame) * ref
echo "
BILDBREITE=${BILDBREITE}
BILDHOEHE=${BILDHOEHE}
MBREITE=${MBREITE}
MHOEHE=${MHOEHE}
MaxFS=${MaxFS}
BIAF420=${BIAF420}
MaxBR="${MaxBR}"
MaxCPB="${MaxCPB}"
MLEVEL=${MLEVEL}
LEVEL=${LEVEL}
CRF=${CRF}
"