# Build and Run x265 codec on Arm servers

## In this learning path

- [Introduction](https://learn.arm.com/learning-paths/servers-and-cloud-computing/codec/)
- [Build and Run x265 codec on Arm servers](https://learn.arm.com/learning-paths/servers-and-cloud-computing/codec/x265/)
- [Next Steps](https://learn.arm.com/learning-paths/servers-and-cloud-computing/codec/_next-steps/)

## Install necessary software packages
`x265` is an open-source H.265/HVEC encoder that offers very high compression efficiency and performance. There have been significant efforts to optimize the open-source libx265 implementation of the H.265 encoder on Arm Neoverse platforms which supports Neon instructions. The optimized code is available on [Bitbucket](https://bitbucket.org/multicoreware/x265_git/).

Install GCC for your Arm Linux distribution. Refer to the [install guide](/install-guides/gcc/native/) for additional information.

Install `Cmake` and other dependencies:

```bash
sudo apt update
sudo apt install wget git cmake cmake-curses-gui build-essential -y
```

If you are running on x86, also install `yasm`:

```bash
sudo apt install  yasm -y
```

## Download and build x265 source
Clone the repository and navigate to the `linux` directory.

```bash
git clone https://bitbucket.org/multicoreware/x265_git.git
cd x265_git/build/linux
```

Run the interactive bash script to change the default flags for the build. Then, run `make`.

```bash
./make-Makefiles.bash
make
```

**Note:** If you encounter an error regarding an unknown value, you can change the `ENABLE_NEON_I8MM` flag to `OFF` using the interactive bash script in the previous step.

```bash
__output__ error: unknown value ‘armv9-a+i8mm+sve2’ for ‘-march’
```

For detailed instructions refer to this [README](https://bitbucket.org/multicoreware/x265_git/src/master/build/README.txt).

## Download video streams to run x265 on and measure performance
To benchmark the compression efficiency and performance of `x265`, you will need a set of video streams to run the codec on. You can use the video files from the [Google YouTube UGC data set](https://console.cloud.google.com/storage/browser/ugc-dataset/original_videos/Sports) with different resolutions.

Download the `360P` and `1080P` video files:

```bash
wget https://storage.googleapis.com/ugc-dataset/original_videos/Sports/360P/Sports_360P-02c3.mkv
wget https://storage.googleapis.com/ugc-dataset/original_videos/Sports/1080P/Sports_1080P-0640.mkv
```

## Run x265 on the sample video files
To benchmark the performance of `x265` over 50 frames of the `360P` video file, run the command:

```bash
./x265 --preset ultrafast --frames 50 Sports_360P-02c3.mkv --input-res 640x360 --fps 24 --output outfile.265 --frame-threads 1 --no-wpp --pools ','
```

To benchmark the performance of `x265`, using the `1080P` video file, run the command:

```bash
./x265 --preset ultrafast --frames 50 Sports_1080P-0640.mkv --input-res 1920x1080 --fps 24 --output outfile.265 --frame-threads 1 --no-wpp --pools ','
```

You can vary the preset settings on the different resolution images and measure the impact on performance.

For full usage instructions, refer to the [command line documentation](https://x265.readthedocs.io/en/master/cli.html), or see the help:

```bash
./x265 --help
```

## View Results
The encoding Frame Rate (Frames per second) for the video files is output at the end of each run.

Shown below is example output from running the codec on the 1080P sample video file:

```bash
__output__ yuv  [info]: 1920x1080 fps 24000/1000 i420p8 frames 0 - 49 of 500
__output__ raw  [info]: output file: outfile.265
__output__ x265 [info]: HEVC encoder version 3.5+38-20255e6f0
__output__ x265 [info]: build info [Linux][GCC 9.4.0][32 bit] 8bit
__output__ x265 [info]: using cpu capabilities: NEON
__output__ x265 [info]: Main profile, Level-4 (Main tier)
__output__ x265 [warning]: No thread pool allocated, --lookahead-slices disabled
__output__ x265 [info]: Slices                              : 1
__output__ x265 [info]: frame threads / pool features       : 1 / none
__output__ x265 [info]: Coding QT: max CU size, min CU size : 32 / 16
__output__ x265 [info]: Residual QT: max TU size, max depth : 32 / 1 inter / 1 intra
__output__ x265 [info]: ME / range / subpel / merge         : dia / 57 / 0 / 2
__output__ x265 [info]: Lookahead / bframes / badapt        : 5 / 3 / 0
__output__ x265 [info]: b-pyramid / weightp / weightb       : 1 / 0 / 0
__output__ x265 [info]: References / ref-limit  cu / depth  : 1 / off / off
__output__ x265 [info]: AQ: mode / str / qg-size / cu-tree  : 1 / 0.0 / 32 / 1
__output__ x265 [info]: Rate Control / qCompress            : CRF-28.0 / 0.60
__output__ x265 [info]: tools: rd=2 psy-rd=2.00 early-skip rskip mode=1 tmvp fast-intra
__output__ x265 [info]: tools: strong-intra-smoothing deblock
__output__ x265 [info]: frame I:      1, Avg QP:32.43  kb/s: 41945.86
__output__ x265 [info]: frame P:     13, Avg QP:32.29  kb/s: 30498.79
__output__ x265 [info]: frame B:     36, Avg QP:35.31  kb/s: 9951.11
__output__ x265 [info]: consecutive B-frames: 14.3% 0.0% 0.0% 85.7%
__output__ encoded 50 frames in 13.74s (3.64 fps), 15933.41 kb/s, Avg QP:34.47
```
