From 97b6c62e53198488bca21887725d031390cad816 Mon Sep 17 00:00:00 2001 From: Levon Gevorgyan Date: Thu, 7 Nov 2024 10:22:13 -0600 Subject: [PATCH] upd README --- README.md | 38 +++++++++++++++++++++++++++----------- scripts/estimate_fg.sh | 42 +++++++++++++++++++++++++----------------- 2 files changed, 52 insertions(+), 28 deletions(-) diff --git a/README.md b/README.md index acc5fd6..3637dd4 100644 --- a/README.md +++ b/README.md @@ -6,10 +6,11 @@ This repository is a simple collection of bash scripts. Scripts have only been t 1. Install required dependencies using `./scripts/install_deps.sh` 2. Build and install ffmpeg from source using `./scripts/build.sh` 3. Install an encoding script using `./scripts/recc_encode_install.sh -I` -4. Benchmark the different encoders using `./scripts/benchmark.sh` +4. Install a film-grain estimation script using `./scripts/estimate_fg.sh -I` +5. Benchmark the different encoders using `./scripts/benchmark.sh` ## Encode script -The installation of the encoding script creates a symlink to this repo's `./scripts/recc_encode.sh` so do NOT remove this repo or the functionality of `encode` will FAIL. The `encode` script is a very simple way to use SvtAv1 for video and Opus for audio for encoding, which are arguably the most ideal encoders as of writing this. `encode` does the following: +The installation of the encoding script creates a symlink to this repo's `./scripts/recc_encode.sh` so do NOT remove this repo or the functionality of `encode` will FAIL. The `encode` script is a very simple way to use SvtAv1-PSY for video and Opus for audio for encoding, which are arguably the most ideal encoders as of writing this. `encode` does the following: - Maps all streams except image streams (effectively no poster/image in the output) - Sets the audio bitrate at 64kbps per channel for each audio track - Formats the audio output channel layout correctly for Opus @@ -20,15 +21,18 @@ The installation of the encoding script creates a symlink to this repo's `./scri - Adds track statistics for proper output video/audio bitrate reporting Read the specifics in the actual file : `./scripts/recc_encode.sh` -``` -encode -i input_file [-p -c -s true/false] [-g NUM] [output_file_name] [-I] [-U] - -p print the command instead of executing it [optional] - -c use cropdetect [default=false, optional] - -s use same container as input [default=false, always mkv, optional] - -g set film grain for encode [optional] - output_file_name if not set, will create at /home/lgevorgyan/ [optional] - -I Install this as /usr/local/bin/encode [optional] - -U Uninstall this from /usr/local/bin/encode [optional] +```bash +encode -i input_file [-p] [-c] [-s] [-v] [-g NUM] [output_file_name] [-I] [-U] + -p print the command instead of executing it + -c use cropdetect + -s use same container as input, default is mkv + -g set film grain for encode + -v Print relevant version info + + output_file_name if not set, will create at /home/lgevorgyan/ + + -I Install this as /usr/local/bin/encode + -U Uninstall this from /usr/local/bin/encode ``` Example usage: - `encode -i input.mkv output.mkv` standard usage @@ -36,6 +40,18 @@ Example usage: - `encode -i input.mkv` no output filename will create an output video in your home folder (~/) - `encode -i input.mkv -g 20` will encode with film-grain synthesis=20 WITH denoising +## Estimate film grain script +The installation of the script creates a symlink to this repo's `./scripts/estimate_fg.sh` so do NOT remove this repo or the functionality of `estimate-film-grain` will FAIL. The `estimate-film-grain` script is a way to estimate the ideal film grain of a video by encoding it at different film grain values and observing at what point does a higher film grain value result in diminishing returns. +```bash +estimate_fg.sh -i input_file [-o output_file] [-l NUM] [-s NUM] [-h NUM] [-I] [-U] + -o file to output results to + -l low value to use as minimum film-grain + -s step value to use increment from low to high film-grain + -h high value to use as maximum film-grain + -I Install this as /usr/local/bin/estimate-film-grain + -U Uninstall this from /usr/local/bin/estimate-film-grain +``` + ## Benchmark script AV1 encode quality is tested against 5 different open source videos using libsvtav1, librav1e, and libaom. Netflix's libvmaf is used to analyze quality of the encodes against the original files. diff --git a/scripts/estimate_fg.sh b/scripts/estimate_fg.sh index 8966306..908ca52 100755 --- a/scripts/estimate_fg.sh +++ b/scripts/estimate_fg.sh @@ -1,12 +1,13 @@ #!/bin/bash usage() { - echo "estimate_fg.sh -i input_file [-l NUM] [-s NUM] [-h NUM] [-I] [-U]" - echo -e "\t-l low value to use as minimum film-grain [optional]" - echo -e "\t-s step value to use increment from low to high film-grain [optional]" - echo -e "\t-h high value to use as maximum film-grain [optional]" - echo -e "\t-I Install this as /usr/local/bin/estimate-film-grain [optional]" - echo -e "\t-U Uninstall this from /usr/local/bin/estimate-film-grain [optional]" + echo "estimate_fg.sh -i input_file [-o output_file] [-l NUM] [-s NUM] [-h NUM] [-I] [-U]" + echo -e "\t-o file to output results to" + echo -e "\t-l low value to use as minimum film-grain" + echo -e "\t-s step value to use increment from low to high film-grain" + echo -e "\t-h high value to use as maximum film-grain" + echo -e "\t-I Install this as /usr/local/bin/estimate-film-grain" + echo -e "\t-U Uninstall this from /usr/local/bin/estimate-film-grain" return 0 } @@ -21,12 +22,13 @@ check_not_negative_optarg() { echoerr() { echo -e "$@" 1>&2; } -OPTS='l:s:h:i:IU' +OPTS='o:l:s:h:i:IU' NUM_OPTS="${#OPTS}" # only using -I or -U MIN_OPT=1 # using all MAX_OPT=$NUM_OPTS +CALLING_DIR="$(pwd)" test "$#" -lt "$MIN_OPT" && echo "not enough arguments" && usage && exit 1 test "$#" -gt "$MAX_OPT" && echo "too many arguments" && usage && exit 1 while getopts "$OPTS" flag; do @@ -45,13 +47,16 @@ while getopts "$OPTS" flag; do exit 0 ;; i) - if [[ "$#" -lt 2 ]]; then - echo "wrong arguments given" + if [[ ! -f "${OPTARG}" ]]; then + echo "${OPTARG} does not exist" usage exit 1 fi INPUT="${OPTARG}" ;; + o) + OUTPUT_FILE="${OPTARG}" + ;; l) check_not_negative_optarg "${OPTARG}" LOW_GRAIN="${OPTARG}" @@ -72,11 +77,6 @@ while getopts "$OPTS" flag; do esac done -if [[ ! -f "$INPUT" ]]; then - echo "file does not exist" - exit 1 -fi - # set default values test ! -n "$LOW_GRAIN" && LOW_GRAIN=0 test ! -n "$STEP_GRAIN" && STEP_GRAIN=5 @@ -172,6 +172,12 @@ segment_video() { # ffmpeg -f concat -safe 0 -i "$SEGMENTS_LIST" -hide_banner -loglevel error -c copy "$OUTPUT_CONCAT" } +get_output_bitrate() { + INPUT="$1" + BPS="$(ffprobe "$INPUT" 2>&1 | grep BPS | grep -v 'TAGS' | tr -d ' ' | cut -d':' -f2)" + echo "scale=3;$BPS / 1000000" | bc -l +} + encode_segments() { cd "$SEGMENT_DIR" || exit mkdir ./encoded || exit @@ -183,13 +189,15 @@ encode_segments() { do OUTPUT_VIDEO="encoded/encoded_$VIDEO" encode -i "$VIDEO" -g $GRAIN "$OUTPUT_VIDEO" - BITRATE="$(mediainfo "$OUTPUT_VIDEO" | tr -s ' ' | grep 'Bit rate : ' | cut -d':' -f2)" - echo -e "\tgrain: $GRAIN, bitrate:$BITRATE" >> "$GRAIN_LOG" + BITRATE="$(get_output_bitrate "$OUTPUT_VIDEO")" + echo -e "\tgrain: $GRAIN, bitrate: $BITRATE" >> "$GRAIN_LOG" done echo >> "$GRAIN_LOG" done - cat "$GRAIN_LOG" + test -n "$OUTPUT_FILE" && cp "$GRAIN_LOG" "$CALLING_DIR/$OUTPUT_FILE" + less "$GRAIN_LOG" + } get_avg_bitrate "$INPUT"