====== AVC-Parameter ermitteln ====== #!/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} "