Benutzer-Werkzeuge

Webseiten-Werkzeuge


avc-parameter_ermitteln

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}
"
/home/http/wiki/data/pages/avc-parameter_ermitteln.txt · Zuletzt geändert: von 127.0.0.1