#!/bin/bash # # small helper for calculation bitrates and resolutions for # videoencoding # # Copyright (c) 2003 Mathias Gumz # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the # "Software"), to deal in the Software without restriction, including # without limitation the rights to use, copy, modify, merge, publish, # distribute, sublicense, and/or sell copies of the Software, and to # permit persons to whom the Software is furnished to do so, subject to # the following conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. MODE="bitrate" FPS="25" COLOR="no" AR="16/9" BITRATE="800" WIDTH="740" HEIGHT="576" INCREMENT="300" display_help() { cat << EOF ABOUT avicalc is a small script to calculate some values which are very important for encoding videos: bitrate and resolution. EOF display_usage cat << EOF BPPS red : < 0.10 : don't do it. please. i beg you! yellow : < 0.15 : It will look bad. cyan : < 0.20 : You will notice blocks, but it will look ok. green : < 0.25 : It will look really good. white : < 0.25 : It won't really improve visually. magenta : > 0.30 : Don't do that either - try a bigger resolution instead. EXAMPLES calculate br for 5 minutes of the movie that will result in a 10mb - file: $> avicalc -m bitrate -s 10mb -d 300 -> 279kbit/s calculate the bpp for this movie: $> avicalc -c -m bpp -r 512x244 -c -b 279 -> 0.8 bpp last output should be displayed red for showing it wont look good for sure. so, display some more resolutions to getting near the final resolution: $> avicalc -c -m lr -b 279 -a 16/9 now choose one of the cyan or (better) green marked resolutions for encoding the avi. LINKS the main-source for this script: http://www.mplayerhq.hu/DOCS/tech/encoding-tips.txt AUTHOR mathias gumz BUGS not yet known EOF } display_usage() { cat << EOF SYNOPSIS avicalc [-Hh] [-c] [-m mode] [-s size -d duration] [-b bitrate [-f fps] [-a aspectration] [-r resolution]] OPTIONS -h display usage -H display full help -m mode (bitrate|bpp|lr) bitrate - calculates the needed br for a wanted endsize of an avi of a given length/duration bpp - calculates the bits per pixel-rate for a given resolution, bitrate and frames per second. bpb - calculates bits per block (16x16) for a given resolution, bitrate and frames per second. lr - display a lot of resolutions and the responding bpp's. enable colormode to see what would look ok. lb - display a lot of resolutions and the responding bpps/bpb for a list of bitrates -s wanted size (x|xKB|xMB) -d duration (in seconds) -b bitrate (in kbit/s) -a aspect ratio (16/9|4/3|1.33) -r resolution (widthxheight) -f fps (25 is default) -i increment (for -m lb) -c color mode EOF } extract_resolution() { WIDTH=`echo $1 | sed -e 's/[^[:digit:]]\+[[:digit:]]*$//g'` HEIGHT=`echo $1 | sed -e 's/^[[:digit:]]*[^[:digit:]]\+//g'` } # $1 - bpp * 10 # $2 - bpp - bits per pixel # $3 - bpb - bits per block # $4 - ar output_bpp() { if [ "$COLOR" == "yes" ]; then if [ "$1" -lt 10 ]; then echo -en "\033[01;31m" elif [ "$1" -lt 15 ]; then echo -en "\033[01;33m" elif [ "$1" -lt 20 ]; then echo -en "\033[01;36m" elif [ "$1" -lt 25 ]; then echo -en "\033[01;32m" elif [ "$1" -lt 30 ]; then echo -en "\033[01;37m" else echo -en "\033[01;35m" fi fi echo "${WIDTH}x${HEIGHT} bitrate: $BITRATE ar: $4 bpp: $2 bpb: $3" if [ "$COLOR" == "yes" ]; then echo -en "\033[00m" fi } # # read cmdlineoptions # while getopts ":hHm:r:b:f:d:i:s:ca:" opts do case "$opts" in h ) display_usage; exit 0;; H ) display_help; exit 0;; m ) MODE="$OPTARG";; c ) COLOR="yes";; a ) AR="$OPTARG";; i ) INCREMENT="$OPTARG";; b ) BITRATE="$OPTARG";; s ) val=`echo "$OPTARG" | sed -e 's/[[:alpha:]]*$//g'` unit=`echo "$OPTARG" | sed -e 's/^[[:digit:]]*\.*[[:digit:]]*//g'` case "$unit" in MB | mb ) SIZE=`echo "print 1024 * 1024 * $val" | bc`;; KB | kb ) SIZE=`echo "print 1024 * $val" | bc`;; esac ;; d ) DURATION="$OPTARG";; r ) extract_resolution "$OPTARG";; f ) FPS="$OPTARG";; esac done case "$MODE" in b | bitrate ) br=`echo "print ($SIZE * 8)/($DURATION*1000)" | bc` echo "needed bitrate : $br kbits/s" ;; bpp | bpb ) bpp=`echo "scale = 2;print ($BITRATE * 1000) / ( $WIDTH * $HEIGHT * $FPS )" | bc` bpb=`echo "scale = 2;print ($bpp * 256)" | bc` ar=`echo "scale = 2; print ($WIDTH / $HEIGHT )" | bc` output_bpp `echo "scale = 0; print $bpp * 100" | bc | sed -e 's/[[:punct:]]*[[:digit:]]*$//g'` "$bpp" "$bpb" "$ar" ;; lr ) WIDTH=720 while [ "$WIDTH" -gt 300 ] do HEIGHT=$(( (( `echo "scale = 2; print ($WIDTH / ($AR))" | bc | sed -e 's/[[:punct:]]*[[:digit:]]*$//g'`+1) / 16 ) * 16)) bpp=`echo "scale = 2;print ($BITRATE * 1000) / ( $WIDTH * $HEIGHT * $FPS )" | bc` bpb=`echo "scale = 2;print ($bpp * 256)" | bc` ar=`echo "scale = 2; print ($WIDTH / $HEIGHT )" | bc` output_bpp `echo "scale = 0; print $bpp * 100" | bc | sed -e 's/[[:punct:]]*[[:digit:]]*$//g'` "$bpp" "$bpb" "$ar" WIDTH=$(( $WIDTH - 16 )) done ;; lb ) BITRATE=300 while [ "$BITRATE" -lt 3000 ] do bpp=`echo "scale = 2;print ($BITRATE * 1000) / ( $WIDTH * $HEIGHT * $FPS )" | bc` bpb=`echo "scale = 2;print ($bpp * 256)" | bc` ar=`echo "scale = 2; print ($WIDTH / $HEIGHT )" | bc` output_bpp `echo "scale = 0; print $bpp * 100" | bc | sed -e 's/[[:punct:]]*[[:digit:]]*$//g'` "$bpp" "$bpb" "$ar" BITRATE=$(( $BITRATE + $INCREMENT )) done ;; esac