mirror of
https://github.com/levogevo/ffmpeg-av1-builder.git
synced 2026-01-15 16:56:18 +00:00
update readme and add gnuplot
This commit is contained in:
34
README.md
34
README.md
@@ -22,17 +22,17 @@ The installation of the encoding script creates a symlink to this repo's `./scri
|
|||||||
Read the specifics in the actual file : `./scripts/recc_encode.sh`
|
Read the specifics in the actual file : `./scripts/recc_encode.sh`
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
encode -i input_file [-p] [-c] [-s] [-v] [-g NUM] [output_file_name] [-I] [-U]
|
encode -i input_file [options]
|
||||||
-p print the command instead of executing it
|
[-p] print the command instead of executing it
|
||||||
-c use cropdetect
|
[-c] use cropdetect
|
||||||
-s use same container as input, default is mkv
|
[-s] use same container as input, default is mkv
|
||||||
-g set film grain for encode
|
[-v] Print relevant version info
|
||||||
-v Print relevant version info
|
[-g NUM] set film grain for encode
|
||||||
|
|
||||||
output_file_name if not set, will create at /home/lgevorgyan/
|
[output_file] if not set, will create at $HOME/
|
||||||
|
|
||||||
-I Install this as /usr/local/bin/encode
|
[-I] Install this as /usr/local/bin/encode
|
||||||
-U Uninstall this from /usr/local/bin/encode
|
[-U] Uninstall this from /usr/local/bin/encode
|
||||||
```
|
```
|
||||||
Example usage:
|
Example usage:
|
||||||
- `encode -i input.mkv output.mkv` standard usage
|
- `encode -i input.mkv output.mkv` standard usage
|
||||||
@@ -43,13 +43,15 @@ Example usage:
|
|||||||
## Estimate film grain script
|
## 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.
|
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
|
```bash
|
||||||
estimate_fg.sh -i input_file [-o output_file] [-l NUM] [-s NUM] [-h NUM] [-I] [-U]
|
estimate-film-grain -i input_file [options]
|
||||||
-o file to output results to
|
[-o output_file] file to output results to
|
||||||
-l low value to use as minimum film-grain
|
[-l NUM] low value to use as minimum film-grain
|
||||||
-s step value to use increment from low to high film-grain
|
[-s NUM] step value to use increment from low to high film-grain
|
||||||
-h high value to use as maximum film-grain
|
[-h NUM] high value to use as maximum film-grain
|
||||||
-I Install this as /usr/local/bin/estimate-film-grain
|
[-p] plot bitrates using gnuplot
|
||||||
-U Uninstall this from /usr/local/bin/estimate-film-grain
|
|
||||||
|
[-I] Install this as /usr/local/bin/estimate-film-grain
|
||||||
|
[-U] Uninstall this from /usr/local/bin/estimate-film-grain
|
||||||
```
|
```
|
||||||
|
|
||||||
## Benchmark script
|
## Benchmark script
|
||||||
|
|||||||
@@ -1,13 +1,14 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
usage() {
|
usage() {
|
||||||
echo "estimate_fg.sh -i input_file [-o output_file] [-l NUM] [-s NUM] [-h NUM] [-I] [-U]"
|
echo "$(basename "$0") -i input_file [options]"
|
||||||
echo -e "\t-o file to output results to"
|
echo -e "\t[-o output_file] file to output results to"
|
||||||
echo -e "\t-l low value to use as minimum film-grain"
|
echo -e "\t[-l NUM] 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[-s NUM] 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[-h NUM] high value to use as maximum film-grain"
|
||||||
echo -e "\t-I Install this as /usr/local/bin/estimate-film-grain"
|
echo -e "\t[-p] plot bitrates using gnuplot"
|
||||||
echo -e "\t-U Uninstall this from /usr/local/bin/estimate-film-grain"
|
echo -e "\n\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
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -22,7 +23,7 @@ check_not_negative_optarg() {
|
|||||||
|
|
||||||
echoerr() { echo -e "$@" 1>&2; }
|
echoerr() { echo -e "$@" 1>&2; }
|
||||||
|
|
||||||
OPTS='o:l:s:h:i:IU'
|
OPTS='po:l:s:h:i:IU'
|
||||||
NUM_OPTS="${#OPTS}"
|
NUM_OPTS="${#OPTS}"
|
||||||
# only using -I or -U
|
# only using -I or -U
|
||||||
MIN_OPT=1
|
MIN_OPT=1
|
||||||
@@ -57,6 +58,9 @@ while getopts "$OPTS" flag; do
|
|||||||
o)
|
o)
|
||||||
OUTPUT_FILE="${OPTARG}"
|
OUTPUT_FILE="${OPTARG}"
|
||||||
;;
|
;;
|
||||||
|
p)
|
||||||
|
PLOT='true'
|
||||||
|
;;
|
||||||
l)
|
l)
|
||||||
check_not_negative_optarg "${OPTARG}"
|
check_not_negative_optarg "${OPTARG}"
|
||||||
LOW_GRAIN="${OPTARG}"
|
LOW_GRAIN="${OPTARG}"
|
||||||
@@ -79,8 +83,8 @@ done
|
|||||||
|
|
||||||
# set default values
|
# set default values
|
||||||
test ! -n "$LOW_GRAIN" && LOW_GRAIN=0
|
test ! -n "$LOW_GRAIN" && LOW_GRAIN=0
|
||||||
test ! -n "$STEP_GRAIN" && STEP_GRAIN=5
|
test ! -n "$STEP_GRAIN" && STEP_GRAIN=2
|
||||||
test ! -n "$HIGH_GRAIN" && HIGH_GRAIN=30
|
test ! -n "$HIGH_GRAIN" && HIGH_GRAIN=20
|
||||||
|
|
||||||
echo "Estimating film grain for $INPUT"
|
echo "Estimating film grain for $INPUT"
|
||||||
echo -e "\tTesting grain from $LOW_GRAIN-$HIGH_GRAIN with $STEP_GRAIN step increments" && sleep 2
|
echo -e "\tTesting grain from $LOW_GRAIN-$HIGH_GRAIN with $STEP_GRAIN step increments" && sleep 2
|
||||||
@@ -99,7 +103,7 @@ get_avg_bitrate() {
|
|||||||
check_bitrate_bounds() {
|
check_bitrate_bounds() {
|
||||||
TEST_BITRATE="$1"
|
TEST_BITRATE="$1"
|
||||||
TARGET_BITRATE="$2"
|
TARGET_BITRATE="$2"
|
||||||
TARGET_DELTA="$(echo "$TARGET_BITRATE * .60" | bc)"
|
TARGET_DELTA="$(echo "$TARGET_BITRATE * .70" | bc)"
|
||||||
DIFF_BITRATE=$((TEST_BITRATE - TARGET_BITRATE))
|
DIFF_BITRATE=$((TEST_BITRATE - TARGET_BITRATE))
|
||||||
DIFF_BITRATE="$(echo ${DIFF_BITRATE#-})"
|
DIFF_BITRATE="$(echo ${DIFF_BITRATE#-})"
|
||||||
echoerr "TEST_BITRATE:\t$TEST_BITRATE"
|
echoerr "TEST_BITRATE:\t$TEST_BITRATE"
|
||||||
@@ -119,10 +123,12 @@ SEGMENT_TIME=4
|
|||||||
MAX_SEGMENTS=6
|
MAX_SEGMENTS=6
|
||||||
TOTAL_SECONDS="$(get_duration "$INPUT")"
|
TOTAL_SECONDS="$(get_duration "$INPUT")"
|
||||||
INPUT_BITRATE="$(get_avg_bitrate "$INPUT")"
|
INPUT_BITRATE="$(get_avg_bitrate "$INPUT")"
|
||||||
SEGMENT_DIR='/tmp/fg_segments'
|
CLEAN_INP_NAME="$(echo "$INPUT" | tr ' ' '.' | tr -d '{}[]+')"
|
||||||
|
SEGMENT_DIR="/tmp/${CLEAN_INP_NAME}/fg_segments"
|
||||||
SEGMENTS_LIST="$SEGMENT_DIR/segments_list.txt"
|
SEGMENTS_LIST="$SEGMENT_DIR/segments_list.txt"
|
||||||
OUTPUT_CONCAT="$SEGMENT_DIR/concatenated.mkv"
|
OUTPUT_CONCAT="$SEGMENT_DIR/concatenated.mkv"
|
||||||
GRAIN_LOG="grain_log.txt"
|
OPTS_HASH="$(echo "$@" | sha256sum | tr -d ' ' | cut -d'-' -f1)"
|
||||||
|
GRAIN_LOG="$SEGMENT_DIR/grain_log-${OPTS_HASH}.txt"
|
||||||
|
|
||||||
segment_video() {
|
segment_video() {
|
||||||
# set number of segments and start times
|
# set number of segments and start times
|
||||||
@@ -151,7 +157,7 @@ segment_video() {
|
|||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
START_TIME="${START_TIMES[$INDEX]}"
|
START_TIME="${START_TIMES[$INDEX]}"
|
||||||
OUTPUT_SEGMENT="$SEGMENT_DIR/segment_$INDEX.mkv"
|
OUTPUT_SEGMENT="$SEGMENT_DIR/segment_${INDEX}.mkv"
|
||||||
echo "START_TIME: $START_TIME"
|
echo "START_TIME: $START_TIME"
|
||||||
ffmpeg -ss "$START_TIME" -i "$INPUT" \
|
ffmpeg -ss "$START_TIME" -i "$INPUT" \
|
||||||
-hide_banner -loglevel error -t "$SEGMENT_TIME" \
|
-hide_banner -loglevel error -t "$SEGMENT_TIME" \
|
||||||
@@ -179,16 +185,16 @@ get_output_bitrate() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
encode_segments() {
|
encode_segments() {
|
||||||
cd "$SEGMENT_DIR" || exit
|
mkdir -p "$SEGMENT_DIR/encoded"
|
||||||
mkdir ./encoded || exit
|
|
||||||
echo > "$GRAIN_LOG"
|
echo > "$GRAIN_LOG"
|
||||||
for VIDEO in $(ls segment*.mkv)
|
for VIDEO in $(ls "$SEGMENT_DIR"/segment_*.mkv)
|
||||||
do
|
do
|
||||||
echo "$VIDEO" >> "$GRAIN_LOG"
|
echo "file: $VIDEO" >> "$GRAIN_LOG"
|
||||||
for GRAIN in $(seq $LOW_GRAIN $STEP_GRAIN $HIGH_GRAIN)
|
for GRAIN in $(seq "$LOW_GRAIN" "$STEP_GRAIN" "$HIGH_GRAIN")
|
||||||
do
|
do
|
||||||
OUTPUT_VIDEO="encoded/encoded_$VIDEO"
|
BASE_VID="$(basename "$VIDEO")"
|
||||||
encode -i "$VIDEO" -g $GRAIN "$OUTPUT_VIDEO"
|
OUTPUT_VIDEO="$SEGMENT_DIR/encoded/encoded_${BASE_VID}"
|
||||||
|
encode -i "$VIDEO" -g "$GRAIN" "$OUTPUT_VIDEO"
|
||||||
BITRATE="$(get_output_bitrate "$OUTPUT_VIDEO")"
|
BITRATE="$(get_output_bitrate "$OUTPUT_VIDEO")"
|
||||||
echo -e "\tgrain: $GRAIN, bitrate: $BITRATE" >> "$GRAIN_LOG"
|
echo -e "\tgrain: $GRAIN, bitrate: $BITRATE" >> "$GRAIN_LOG"
|
||||||
done
|
done
|
||||||
@@ -200,6 +206,63 @@ encode_segments() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
plot() {
|
||||||
|
mapfile -t FILES< <( grep "file:" "$GRAIN_LOG" | cut -d':' -f2 | tr -d ' ' | sort | uniq )
|
||||||
|
mapfile -t GRAINS< <( grep "grain:" "$GRAIN_LOG" | cut -d':' -f2 | cut -d',' -f1 | tr -d ' ' | sort -Vu)
|
||||||
|
declare -a BITRATE_SUMS=()
|
||||||
|
|
||||||
|
for FILE in "${FILES[@]}"
|
||||||
|
do
|
||||||
|
# get grains for each file
|
||||||
|
LINE_FILE="$(grep -n "$FILE" "$GRAIN_LOG" | cut -d':' -f1 )"
|
||||||
|
START_GRAIN_LINE="$(echo "$LINE_FILE + 1" | bc)"
|
||||||
|
END_GRAIN_LINE="$(echo "$LINE_FILE + ${#GRAINS[@]}" | bc)"
|
||||||
|
GRAINS_FOR_FILE="$(sed -n "$START_GRAIN_LINE, $END_GRAIN_LINE p" "$GRAIN_LOG")"
|
||||||
|
# set baseline bitrate value
|
||||||
|
BASELINE_BITRATE="$(echo "$GRAINS_FOR_FILE" | tr -d ' ' | grep "grain:${GRAINS[0]}" | cut -d':' -f3)"
|
||||||
|
# get sum of bitrate percentages
|
||||||
|
for GRAIN in "${GRAINS[@]}"
|
||||||
|
do
|
||||||
|
COMPARE_BITRATE="$(echo "$GRAINS_FOR_FILE" | tr -d ' ' | grep "grain:$GRAIN" | cut -d':' -f3)"
|
||||||
|
BITRATE_PERCENTAGE="$(echo "$COMPARE_BITRATE / $BASELINE_BITRATE" | bc -l)"
|
||||||
|
# fix NULL BITRATE_SUM for first comparison
|
||||||
|
test -n "${BITRATE_SUMS[$GRAIN]}" || BITRATE_SUMS["$GRAIN"]=0
|
||||||
|
BITRATE_SUMS["$GRAIN"]="$(echo "$BITRATE_PERCENTAGE + ${BITRATE_SUMS[$GRAIN]}" | bc -l)"
|
||||||
|
done
|
||||||
|
done
|
||||||
|
|
||||||
|
# clear plot file
|
||||||
|
PLOT="$SEGMENT_DIR/plot.dat"
|
||||||
|
echo -n > "$PLOT"
|
||||||
|
|
||||||
|
# set average bitrates per grain
|
||||||
|
for GRAIN in "${GRAINS[@]}"
|
||||||
|
do
|
||||||
|
AVG_BITRATE="$(echo "${BITRATE_SUMS[$GRAIN]} / ${#FILES[@]}" | bc -l)"
|
||||||
|
echo -e "$GRAIN\t$AVG_BITRATE" >> "$PLOT"
|
||||||
|
done
|
||||||
|
|
||||||
|
# set terminal size
|
||||||
|
TERMINAL="$(tty)"
|
||||||
|
COLUMNS=$(stty -a <"$TERMINAL" | grep -Po '(?<=columns )\d+')
|
||||||
|
ROWS=$(stty -a <"$TERMINAL" | grep -Po '(?<=rows )\d+')
|
||||||
|
|
||||||
|
# plot data
|
||||||
|
gnuplot -p -e " \
|
||||||
|
set terminal dumb size $COLUMNS, $ROWS; \
|
||||||
|
set autoscale; \
|
||||||
|
set style line 1 \
|
||||||
|
linecolor rgb '#0060ad' \
|
||||||
|
linetype 1 linewidth 2 \
|
||||||
|
pointtype 7 pointsize 1.5; \
|
||||||
|
plot '$PLOT' with linespoints linestyle 1
|
||||||
|
"
|
||||||
|
}
|
||||||
|
|
||||||
|
test "$PLOT" == 'true' && test -f "$GRAIN_LOG" && \
|
||||||
|
{ plot ; exit $? ; }
|
||||||
get_avg_bitrate "$INPUT"
|
get_avg_bitrate "$INPUT"
|
||||||
segment_video
|
segment_video
|
||||||
encode_segments
|
encode_segments
|
||||||
|
test "$PLOT" == 'true' && test -f "$GRAIN_LOG" && \
|
||||||
|
{ plot ; }
|
||||||
@@ -9,15 +9,15 @@ SCRIPT_DIR="$(dirname "$SCRIPT_PATH")"
|
|||||||
BUILDER_DIR="$(dirname "$SCRIPT_DIR")"
|
BUILDER_DIR="$(dirname "$SCRIPT_DIR")"
|
||||||
|
|
||||||
usage() {
|
usage() {
|
||||||
echo "encode -i input_file [-p] [-c] [-s] [-v] [-g NUM] [output_file_name] [-I] [-U] "
|
echo "$(basename "$0") -i input_file [options] "
|
||||||
echo -e "\t-p print the command instead of executing it"
|
echo -e "\t[-p] print the command instead of executing it"
|
||||||
echo -e "\t-c use cropdetect"
|
echo -e "\t[-c] use cropdetect"
|
||||||
echo -e "\t-s use same container as input, default is mkv"
|
echo -e "\t[-s] use same container as input, default is mkv"
|
||||||
echo -e "\t-g set film grain for encode"
|
echo -e "\t[-v] Print relevant version info"
|
||||||
echo -e "\t-v Print relevant version info"
|
echo -e "\t[-g NUM] set film grain for encode"
|
||||||
echo -e "\n\toutput_file_name if not set, will create at $HOME/\n"
|
echo -e "\n\t[output_file] if not set, will create at $HOME/"
|
||||||
echo -e "\t-I Install this as /usr/local/bin/encode"
|
echo -e "\n\t[-I] Install this as /usr/local/bin/encode"
|
||||||
echo -e "\t-U Uninstall this from /usr/local/bin/encode"
|
echo -e "\t[-U] Uninstall this from /usr/local/bin/encode"
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user