Video Compression

VideoNerd

Content

Getting x265 codec

Compilation x265

Running of x265

 How Run x265 in Parallel

Encode in Lossless Mode

Encode in Constant QP Mode

How Run x265 via ffmpeg

Disadvantages of x265

Example Code of using libx265.lib

Getting x265 codec

to take open-source x265 you need Mercurial Tortoise hg installed, and to download x265 sources (for details see https://www.mercurial-scm.org/wiki/Download)

hg clone    http://hg.videolan.org/x265

Notice: x265 is encoder only, there is no option to decode.

There is a git repository of x265: git clone https://github.com/videolan/x265

 

Compilation x265

Linux

In the folder x265\build\linux apply make-Makefiles.bash to generate corresponding Makefile (according to parameters in CMakeCache.txt)

./make-Makefiles.bash make

If you need x265 in debug mode then write CMAKE_BUILD_TYPE:STRING=Debug in CMakeCache.txt

The bin-file x265 is created with libx265.a libx265.so libraries.

 

Windows

Enter to appropriate VisualStudio solutions in  x265\build and run the batch file  make-solutions.

For Visual Studio version 2019 i recommend  in the folder builds/vc15-x86_64  open with an editor make_solutions.bat and replace “Visual Studio 2015” with the 2019’s versions as follows:

cmake -G "Visual Studio 16 2019"  ..\..\source && cmake-gui ..\..\source

and to run make_solutions

There are opened a pop-up window to select configuration (i prefer defaults). Upon configuration is chosen press “Generate” button and VisualStudio solution is produced.

Open the solution and build firstly ‘x265-static’ project and then ‘cli’ project. As result of building ‘cli’ project the self-contained x265.exe is generated.

Running of x265

Command line simplified template

x265 --input yuv_file --input-res WxH --fps N  -o 265_file

Advanced Example [ encode 30 frames, bitrate – 3Mbps, gop size 10 frames, no B frames]

x265 --input container_cif.yuv --input-res 352x288 --fps 24 --b-adapt 0    -b 0 --ref 1 --no-scenecut --keyint 10 --min-keyint 10 --repeat-headers --bitrate 3000 --frames 30 -o test.h265

Notes:

--no-scenecut disables scene-cut detection and to prevent insertion of I-frame if a scenecut detected.

--repeat-headers emits VPS/SPS/PPS at the start of each keyframe

-b 0  disables B-frames, each GOP is IPPPP

 

Example: Generation of Stream with B-frames

Use the following options to enable B frames:

‘-b 1’ – single B-frames between I/P

'--ref 1' – single reference in each direction

'--no-b-pyramid --b-adapt 0' – to make GOP structure ‘flat’ with repetitive pattern IPB

Note:   ‘veryslow’ preset makes x265 encoding speed very low, to boost the encoding speed you can enable the early skip mode ('--early-skip'):

  x265  --input    test.yuv   --input-res 1920x1080    --fps 24   --preset  veryslow --early-skip --qp 32  --b-adapt 0 -b 2 --no-scenecut --keyint 24 --min-keyint 24 --repeat-headers --no-open-gop  --ipratio 1.0 --pbratio 1.0 -o test_cqp32_veryslow.hevc

 

Example [closed gops of length 60 frames, frame rate 60 fps, encode 120 frames, bitrate 10Mbps, print the average SSIM]

--ssim indicates to compute SSIM scores per frame and to print the average SSIM score of luminance.

 

x265 --input Fifa17.yuv --input-res 1920x1080 --ssim --fps 60 --b-adapt 0 -b 0 --ref 1 --no-scenecut --keyint 60 --min-keyint 60 --no-open-gop --repeat-headers --bitrate 10000 --frames 120 -o test.h265

….

encoded 120 frames in 9.75s (12.31 fps), 9917.61 kb/s, Avg QP:29.75, SSIM Mean Y: 0.9579783

 

How Run x265 in Parallel

x265 supports two paralleling schemas: frame-level and WPP (tiles not supported by x265 yet). It’s worth mentioning that applying parallel coding might deteriorate coding efficiency (reported that WPP deteriorates the coding efficiency by 1%)

Frame Level Parallelism

First thread/core  starts the k-th frame, the second thread/core waits until a several mb-rows of the k-th frame completed. Then the second thread/core commences, since search area (although limited) is already available.

To enable frame-level parallelism you need disable WPP (use ‘--no-wpp’) and apply ‘--frame-threads’ (no co-existence of WPP and frame-threads) by setting ‘--frame-threads N’, where N is the number of threads.

Example (2 concurrently encoded frames):

 x265 --input a.yuv --input-res 3840x1744 --fps 24   --b-adapt 0  -b 0 --ref 1  --frame-threads 2     --no-wpp    --rc-lookahead 2 -o test.h265

Note: when --rc-lookahead 1 encoding time is greater than when --rc-lookahed 30, setting lookahead to zero significantly increases the encoding time.

 

MB-level Parallelism

MB-level parallelism is realized by means of built-in tool WPP. To enable mb-level parallelism with N threads you need disable frame multi-threading (by setting ‘--frame-threads 1’), enable wpp (--wpp) and set the number of threads (--threads N).

 x265 --input a.yuv --input-res 3840x1744 --fps 24   --b-adapt 0  -b 0 --ref 1    --threads N --frame-threads 1  --wpp   --rc-lookahead 2 -o test1.h265

 

Performance Results:

  • Performance of single-thread coding [100 frames of 1080p, the bitrate 10Mbps, no B frames]:

x265 --input test.yuv --input-res 1920x1080 --fps 60 --b-adapt 0 -b 0 --ref 1 --no-scenecut --keyint 60 --min-keyint 60 --repeat-headers   --bitrate 10000 --no-wpp         --frame-threads 1 --rc-lookahead 2 --frames 100    -o  test.h265

encoded 100 frames in 78.88s (1.27 fps), 8342.64 kb/s

  • Performance Frame-Level Parallelism on dual-cores [100 frames of 1080p, the bitrate 10Mbps, no B frames]:

x265 --input test.yuv --input-res 1920x1080 --fps 60 --b-adapt 0 -b 0 --ref 1 --no-scenecut --keyint 60 --min-keyint 60 --repeat-headers    --bitrate 10000 --no-wpp                --frame-threads 2 --rc-lookahead 2 --frames 100    -o  test.h265

encoded 100 frames in 55.95s (1.79 fps), 8236.90 kb/s

  • Performance MB-level Parallelism with WPP [100 frames of 1080p, 10Mbps]:

x265 --input test.yuv --input-res 1920x1080 --fps 60 --b-adapt 0 -b 0 --ref 1 --no-scenecut --keyint 60 --min-keyint 60 --repeat-headers       --bitrate 10000 --wpp                 --frame-threads 1 --rc-lookahead 2 --frames 100    -o  test.h265

encoded 100 frames in 37.99s (2.63 fps), 8343.92 kb/s, Avg QP:29.47

 

Conclusion: 

MB-based mode provides maximal parallelism (~2x speed-up).

 

Encode in Lossless Mode

For medical applications it’s required to encode images in lossless mode to avoid diagnostic errors. HEVC supports lossless coding. To activate lossless coding with x265 one should use ‘–lossless’ and ‘–cu-lossless’ keys in the command line. i recommend the following parameters for 4:2:0 video lossless coding:

x265  --input <yuv-file>  --input-res WxH --fps R --cu-lossless --lossless  --b-adapt 0  -b 2 --ref 1 --no-scenecut --keyint 30 --min-keyint 30 --repeat-headers  -o  <lossless-h265>

According to my observations, HEVC lossless coding of natural 4:2:0 images (8 bpp, with x265) gives compression ratios in the range 3:1 to 4:1.

 

Encode in Constant QP Mode

Example, encode IPbb GOP structure with constant QP (QP=32) for all frames:

     x265  --input    test.yuv   --input-res 1920x1080    --fps 24   --preset  veryslow --qp 32  --b-adapt 0 -b 2 --no-scenecut --keyint 24 --min-keyint 24 --repeat-headers --no-open-gop  --ipratio 1.0 --pbratio 1.0 -o test_cqp32_veryslow.hevc

--qp 32  sets constant QP mode with QP=32 for I-frames

--ipratio 1.0   makes QP=32 for P frames

--pbratio 1.0 makes QP=32 for B frames

 

How Run x265 via ffmpeg

If your ffmpeg is configured to support x265 then the following command illustrates as to configure and to encode x265 (closed gops, 60 frames in each gop, the rate control is CRF, no B-frames):

ffmpeg -s:v 352×288 -pix_fmt yuv420p  -i test.yuv  -c:v libx265 -x265-params crf=26:wpp=0:slices=0:fps=60:ref=1:open-gop=0:keyint=60:min-keyint=60:bframes=0   test.h265

x265 is configured via ‘-x265-params’

 

ffmpeg supports the following parameters for configuring Rate Control (regardless chosen encoder):

  • b:v  specifies target bitrate 
  • maxrate specifies peak bitrate
  • bufsize is important parameters for Rate Control methods based on virtual buffer size. Rate Control keeps a virtual buffer which mimics the input buffer at Decoder’s side and the purpose of Rate Control not to violate this virtual buffer (mainly not to overwhelm Decoder). For low latency applications it’s worth to keep ‘bufsize’ small (say 30ms of payload).

 

Example [ target bitrate 5Mbps, the peak bitrate is 6Mbps, bufsize is 30ms of payload with the target rate –  5M x 0.03 = 0.15M = 150 kbps]:

   -b:v 5M -maxrate 6M -bufsize 150k

if input is yuv it’s worth to specify the frame rate with ‘-r’ (otherwise the default 25fps taken)

Example [ target 10Mbps, frame rate 60fps, GOP structure – IPPP ]

ffmpeg -y -s 1920×1080 -i .test1920x1080.yuv -c:v libx265 -r 60 -g 60 -keyint_min 60 -b:v 10000k -maxrate 11000k -x265-params ref=1:bframes=0 test.h265

 

 

Disadvantages of x265

Tiles not supported.

Why tiles are important?

1) Tiles provides slightly better coding efficiency than slices:

For example, if we divide a WxH frame into 4 uniform slices then the total length of internal boundaries is 3xW.

On the other hand, if we divide uniformly this frame into 4 tiles then the total length of internal boundaries is (W+H). In most cases W+H < 3xW.

Hence the division into tiles tends to be more beneficial than that into slices, since the total length of boundaries is minimized for tiles and inter-CTU prediction gets better respectively. Moreover, slice headers adds additional overhead.

2) Tiles are necessary for 360/VR streaming applications.

The new form of coding and packing Tiled Video Streaming has been adopted by MPEG committee as an amendment to HEVC/ISOBMFF. This solution requires HEVC encoding and tiling.
Each frame is divided into a fixed grid of tiles (not necessarily uniform), each tile is encoded independently with tile-constrained motion prediction (no motion vector crosses tile/picture boundaries) and without deblocking filtering across tile boundaries.

 

Example Code of using libx265.lib

Upon compilation of x265 sources libx265.lib is created. You can write your own hevc codec using libx265.lib and API of x265.h.

I took and modified test code (the simplest encoder which takes yuv and encode) from here  to example.cpp .

The setting in example.cpp is default, so, you can change settings as you wish within the code. I compiled example.cpp in windows, for compilation i use MinGW, as follows:
 
 gcc -o example.exe  -I. -I./source  example.cpp  -L. -lx265
 
Notes:
h-files are located under the folder ‘sources‘ of x265, therefore '-I./source' added
in addition x265_config.h is required and i put it in the working directory ( ‘-I.’ ).
libx265.lib for Windows, i put this library file in the working directory, therefor ‘-L.’ is used
To run example.exe you need two dll-files:  libx265.dll and msys-2.0.dll
Example
example.exe  352x288  akiyo_cif.yuv   test.h265

22 Responses

  1. Hiya, I’m really glad I have found this information. Today bloggers publish just about gossips and net and this is really frustrating. A good site with exciting content, that’s what I need. Thank you for keeping this web-site, I will be visiting it. Do you do newsletters? Can not find it.

  2. This web site is really a walk-through for all the data you wished about this and didn’t know who to ask. Glimpse right here, and you’ll positively discover it.

  3. Wonderful blog! I found it while surfing around on Yahoo News. Do you have any tips on how to get listed in Yahoo News? I’ve been trying for a while but I never seem to get there! Many thanks

  4. Have you ever considered publishing an e-book or guest authoring on other sites? I have a blog centered on the same topics you discuss and would love to have you share some stories/information. I know my viewers would value your work. If you’re even remotely interested, feel free to shoot me an e-mail.

  5. This is the right blog for anyone who wants to find out about this topic. You realize so much its almost hard to argue with you (not that I actually would want…HaHa). You definitely put a new spin on a topic thats been written about for years. Great stuff, just great!

  6. I’ve been absent for some time, but now I remember why I used to love this blog. Thanks , I will try and check back more frequently. How frequently you update your website?

  7. I discovered your weblog web site on google and verify a few of your early posts. Continue to keep up the superb operate. I just further up your RSS feed to my MSN Information Reader. In search of ahead to reading more from you afterward!?

  8. I haven?t checked in here for a while as I thought it was getting boring, but the last several posts are good quality so I guess I?ll add you back to my daily bloglist. You deserve it my friend 🙂

  9. Hello my friend! I want to say that this post is awesome, nice written and include approximately all significant infos. I?d like to see more posts like this.

Leave a Reply

Your email address will not be published. Required fields are marked *