This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

AM62A7: HEVC encoder: I don't see any difference in encoding with different bitrates/levels

Part Number: AM62A7

Hi Suren,

I'm running into the same problem again, I can't see any difference in the different compression levels.

I use the following script to build my pipeline:

#!/bin/bash

INPUT="frame.jpg"
OUTPUT="output"
HEVC_PROFILE="main"
HEVC_LEVEL="1"
VIDEO_BITRATE=0
# VIDEO_BITRATE_MODE: 0 = on, 1 = off
VIDEO_BITRATE_MODE=0
FRAME_RATE_CONTROL=0

TEMP=$(getopt -o 'p:l:b:i:o:h' --long 'profile:,level:,bitrate:,bitratemode:,perframe,input:,output:,help' -n '$0' -- "$@")

if [ $? -ne 0 ]; then
	echo 'Terminating...' >&2
	exit 1
fi

eval set -- "$TEMP"
unset TEMP

while true; do
	case "$1" in
		'-h'|'--help')
			echo "$0 - H.265 compress a JPEG file into a one second stream"
			echo "Parameters:"
			echo "  -p main|main-still-picture|main-10 (HEVC Profile)"
			echo "  -l 1|2|2.1|3|3.1|4|4.1|5|5.1 (HEVC Level)"
			echo "  -b 0..700000000 (Video Bitrate)"
			echo "  -i input.jpg (Input JPEG file)"
			echo "  -o output (Base name of output files - gets converted to output%03d.jpg)"
			echo "  -h This help"
			exit 0
			shift
			continue
		;;
		'-p'|'--profile')
			case "$2" in
				'main'|'Main'|'0')
					HEVC_PROFILE="main"
					;;
				'main-still-picture'|'1')
					HEVC_PROFILE="main-still-picture"
					;;
				'main-10'|'2')
					HEVC_PROFILE="main-10"
					;;
				*)
					HEVC_PROFILE="main"
					;;
			esac
			echo "HEVC Profile: '$HEVC_PROFILE'"
			shift 2
			continue
		;;
		'-l'|'--level')
			case "$2" in
				'1'|'2'|'2.1'|'3'|'3.1'|'4'|'4.1'|'5'|'5.1')
					HEVC_LEVEL="$2"
					;;
				*)
					HEVC_LEVEL="1"
					;;
			esac
			echo "HEVC Level: '$HEVC_LEVEL'"
			shift 2
			continue
		;;
		'-b'|'--bitrate')
			echo "Video Bitrate: '$2'"
			VIDEO_BITRATE=$2
			shift 2
			continue
		;;
		'-i'|'--input')
			echo "Input: '$2'"
			INPUT=$2
			shift 2
			continue
		;;
		'-o'|'--output')
			echo "Output: '$2'"
			OUTPUT=$2
			shift 2
			continue
		;;
		'--bitratemode')
			echo "Video Bitrate Mode: $2"
			VIDEO_BITRATE_MODE=$2
			shift 2
			continue
		;;
		'--perframe')
			echo "Frame Rate per Frame"
			FRAME_RATE_CONTROL=1
			shift
			continue
		;;
		'--')
			shift
			break
		;;
		*)
			echo 'Internal error!' >&2
			exit 1
		;;
	esac
done

#if [ $VIDEO_BITRATE -gt 0 ]; then
#	FRAME_RATE_CONTROL=1
#fi

echo -n "Compressing $INPUT to $OUTPUT:"
gst-launch-1.0 -q multifilesrc location="$INPUT" start-index=0 stop-index=29 caps="image/jpeg,framerate=30/1" loop=0 \
  ! jpegparse \
  ! jpegdec \
  ! 'video/x-raw,format=I420' \
  ! videoconvert \
  ! v4l2h265enc extra-controls="controls, prepend_sps_and_pps_to_idr=1, frame_level_rate_control_enable=${FRAME_RATE_CONTROL}, video_gop_size=5, video_bitrate_mode=${VIDEO_BITRATE_MODE}, video_bitrate=$VIDEO_BITRATE" \
  ! "video/x-h265, profile=(string)${HEVC_PROFILE}, level=(string)${HEVC_LEVEL}" \
  ! tee name=tee0 \
  ! h265parse \
  ! v4l2h265dec \
  ! jpegenc \
  ! multifilesink location="${OUTPUT}-p${HEVC_PROFILE}l${HEVC_LEVEL}b${VIDEO_BITRATE}m${VIDEO_BITRATE_MODE}f${FRAME_RATE_CONTROL}.%03d.jpg" \
  tee0. \
  ! filesink location="${OUTPUT}-p${HEVC_PROFILE}l${HEVC_LEVEL}b${VIDEO_BITRATE}m${VIDEO_BITRATE_MODE}f${FRAME_RATE_CONTROL}.h265"
echo "Done."

I have some input files at google drive, this includes the script above.

When I call the script multiple times with different parameters:

./h265-compress -i "Frame %d.jpg" -o onsemi2 -p main -l 5.1 -b 6000 --bitratemode 1
./h265-compress -i "Frame %d.jpg" -o onsemi2 -p main -l 5.1 -b 6000 --bitratemode 1 --perframe
./h265-compress -i "Frame %d.jpg" -o onsemi2 -p main -l 5.1 -b 6000 --bitratemode 0
./h265-compress -i "Frame %d.jpg" -o onsemi2 -p main -l 5.1 -b 6000 --bitratemode 0 --perframe
./h265-compress -i "Frame %d.jpg" -o onsemi2 -p main -l 3 -b 1000 --bitratemode 1
./h265-compress -i "Frame %d.jpg" -o onsemi2 -p main -l 3 -b 1000 --bitratemode 1 --perframe
./h265-compress -i "Frame %d.jpg" -o onsemi2 -p main -l 3 -b 1000 --bitratemode 0 --perframe
./h265-compress -i "Frame %d.jpg" -o onsemi2 -p main -l 3 -b 1000 --bitratemode 0
  

I get the same output:

-rw-r--r-- 1 root root 3112480 Feb 13 06:50 onsemi2-pmainl3b1000m0f0.h265
-rw-r--r-- 1 root root  163960 Feb 13 06:48 onsemi2-pmainl3b1000m0f1.h265
-rw-r--r-- 1 root root 3112480 Feb 13 06:44 onsemi2-pmainl3b1000m1f0.h265
-rw-r--r-- 1 root root  163960 Feb 13 06:46 onsemi2-pmainl3b1000m1f1.h265
-rw-r--r-- 1 root root 3112480 Feb 13 06:55 onsemi2-pmainl5.1b6000m0f0.h265
-rw-r--r-- 1 root root  163960 Feb 13 07:04 onsemi2-pmainl5.1b6000m0f1.h265
-rw-r--r-- 1 root root 3112480 Feb 13 06:40 onsemi2-pmainl5.1b6000m1f0.h265
-rw-r--r-- 1 root root  163960 Feb 13 06:42 onsemi2-pmainl5.1b6000m1f1.h265

The only setting that seems to make a difference is the frame_level_rate_control_enable setting (f0 and f1 in the filenames).

My questions:

* How do I set things up in such a way that the bitrate is taken into account?

* What does the hevc_profile and hevc_level do exactly?

The ultimate goal is to get a stream with a bitrate of 6 Mbps, with variable bitrate enabled.

Bas Vermeulen

  • Hi Bas,

    video_btirate_mode set to 1 (default) is for constant bitrate. Thanks for the script and the files, let me test the variable bit mode and revert back with the results.

    Best Regards,

    Suren

  • I've since tested the same thing on x86 with the x265enc encoder, and there different bitrates give different output. However, the only setting I can set is the bitrate itself. Setting different bitrates gives me different results.

    If you like, I can send you the scripts for that as well, just let me know.

  • Bas,

    For your understanding,

    • frame_level_rate_control_enable
      • 0 : constant QP
      • 1 : select one of video_bitrate_mode
    • video_bitrate_mode
      • 0 : VBR (vbvBufferSize = 3000 . fixed. can't be changed)
      • 1 : CBR (vbvBufferSize is set by vbv_buffer_size host set )

    VBR: v4l2h264enc extra-controls="controls, video_bitrate=500000, video_bitrate_mode=0, vbv_buffer_size=3000, frame_level_rate_control_enable=1"

    CBR: v4l2h264enc extra-controls="controls, video_bitrate=500000, video_bitrate_mode=0, vbv_buffer_size=10, frame_level_rate_control_enable=1"

    See if with these parameters you are able to see the difference.

    Best Regards,

    Suren

  • Hi Suren,

    That helped a lot, thank you.

    To summarize:

    frame_level_rate_control_enable:

    • constant QP
    • select one of video_bitrate_mode

    video_bitrate_mode:

    • 0: VBR (this sets and/or requires vbv_buffer_size=3000)
    • 1: CBR (vbv_buffer_size also needs to be set)

    video_bitrate:

    • value in bits per second, so 6000000 for 6 Mbps

    prepend_sps_and_pps_to_idr:

    • 0
    • 1: needed for an RTP stream to be able to start after the server starts streaming.

    What does QP stand for?

    Regards,

    Bas Vermeulen

  • And would it be possible to document this somewhere? I'm fairly sure that other people won't be able to find the correct settings either.

    Thanks,

    Bas Vermeulen