1# libgav1 -- an AV1 decoder 2 3libgav1 is a Main profile (0), High profile (1) & Professional profile (2) 4compliant AV1 decoder. More information on the AV1 video format can be found at 5[aomedia.org](https://aomedia.org). 6 7[TOC] 8 9## Building 10 11### Prerequisites 12 131. A C++11 compiler. gcc 6+, clang 7+ or Microsoft Visual Studio 2017+ are 14 recommended. 15 162. [CMake >= 3.7.1](https://cmake.org/download/) 17 183. [Abseil](https://abseil.io) 19 20 From within the libgav1 directory: 21 22 ```shell 23 $ git clone -b 20220623.0 --depth 1 \ 24 https://github.com/abseil/abseil-cpp.git third_party/abseil-cpp 25 ``` 26 27 Note: Abseil is required by the examples and tests. libgav1 will depend on 28 it if `LIBGAV1_THREADPOOL_USE_STD_MUTEX` is set to `0` (see below). 29 304. (Optional) [GoogleTest](https://github.com/google/googletest) 31 32 From within the libgav1 directory: 33 34 ```shell 35 $ git clone -b release-1.12.1 --depth 1 \ 36 https://github.com/google/googletest.git third_party/googletest 37 ``` 38 39### Compile 40 41```shell 42 $ mkdir build && cd build 43 $ cmake -G "Unix Makefiles" .. 44 $ make 45``` 46 47Configuration options: 48 49* `LIBGAV1_MAX_BITDEPTH`: defines the maximum supported bitdepth (8, 10, 12; 50 default: 12). 51* `LIBGAV1_ENABLE_ALL_DSP_FUNCTIONS`: define to a non-zero value to disable 52 [symbol reduction](#symbol-reduction) in an optimized build to keep all 53 versions of dsp functions available. Automatically defined in 54 `src/dsp/dsp.h` if unset. 55* `LIBGAV1_ENABLE_AVX2`: define to a non-zero value to enable avx2 56 optimizations. Automatically defined in `src/utils/cpu.h` if unset. 57* `LIBGAV1_ENABLE_NEON`: define to a non-zero value to enable NEON 58 optimizations. Automatically defined in `src/utils/cpu.h` if unset. 59* `LIBGAV1_ENABLE_SSE4_1`: define to a non-zero value to enable sse4.1 60 optimizations. Automatically defined in `src/utils/cpu.h` if unset. Note 61 setting this to 0 will also disable AVX2. 62* `LIBGAV1_ENABLE_LOGGING`: define to 0/1 to control debug logging. 63 Automatically defined in `src/utils/logging.h` if unset. 64* `LIBGAV1_EXAMPLES_ENABLE_LOGGING`: define to 0/1 to control error logging in 65 the examples. Automatically defined in `examples/logging.h` if unset. 66* `LIBGAV1_ENABLE_TRANSFORM_RANGE_CHECK`: define to 1 to enable transform 67 coefficient range checks. 68* `LIBGAV1_LOG_LEVEL`: controls the maximum allowed log level, see `enum 69 LogSeverity` in `src/utils/logging.h`. Automatically defined in 70 `src/utils/logging.cc` if unset. 71* `LIBGAV1_THREADPOOL_USE_STD_MUTEX`: controls use of std::mutex and 72 absl::Mutex in ThreadPool. Defining this to 1 will remove any Abseil 73 dependency from the core library. Automatically defined in 74 `src/utils/threadpool.h` if unset. Defaults to 1 on Android & iOS, 0 75 otherwise. 76* `LIBGAV1_MAX_THREADS`: sets the number of threads that the library is 77 allowed to create. Has to be an integer > 0. Otherwise this is ignored. The 78 default value is 128. 79* `LIBGAV1_FRAME_PARALLEL_THRESHOLD_MULTIPLIER`: the threshold multiplier that 80 is used to determine when to use frame parallel decoding. Frame parallel 81 decoding will be used if |threads| > |tile_count| * this multiplier. Has to 82 be an integer > 0. The default value is 4. This is an advanced setting 83 intended for testing purposes. 84 85For additional options see: 86 87```shell 88 $ cmake .. -LH 89``` 90 91## Testing 92 93* `gav1_decode` can be used to decode IVF files, see `gav1_decode --help` for 94 options. Note: tools like [FFmpeg](https://ffmpeg.org) can be used to 95 convert other container formats to IVF. 96 97* Unit tests are built when `LIBGAV1_ENABLE_TESTS` is set to `1`. The binaries 98 can be invoked directly or with 99 [`ctest`](https://cmake.org/cmake/help/latest/manual/ctest.1.html). 100 101 * The test input location can be given by setting the 102 `LIBGAV1_TEST_DATA_PATH` environment variable; it defaults to 103 `<libgav1_src>/tests/data`, where `<libgav1_src>` is `/data/local/tmp` 104 on Android platforms or the source directory configured with cmake 105 otherwise. 106 107 * Output is written to the value of the `TMPDIR` or `TEMP` environment 108 variables in that order if set, otherwise `/data/local/tmp` on Android 109 platforms, the value of `LIBGAV1_FLAGS_TMPDIR` if defined during 110 compilation or the current directory if not. 111 112## Development 113 114### Contributing 115 116See [CONTRIBUTING.md](CONTRIBUTING.md) for details on how to submit patches. 117 118### Style 119 120libgav1 follows the 121[Google C++ style guide](https://google.github.io/styleguide/cppguide.html) with 122formatting enforced by `clang-format`. 123 124### Comments 125 126Comments of the form '`// X.Y(.Z).`', '`Section X.Y(.Z).`' or '`... in the 127spec`' reference the relevant section(s) in the 128[AV1 specification](http://aomediacodec.github.io/av1-spec/av1-spec.pdf). 129 130### DSP structure 131 132* `src/dsp/dsp.cc` defines the main entry point: `libgav1::dsp::DspInit()`. 133 This handles cpu-detection and initializing each logical unit which populate 134 `libgav1::dsp::Dsp` function tables. 135* `src/dsp/dsp.h` contains function and type definitions for all logical units 136 (e.g., intra-predictors) 137* `src/utils/cpu.h` contains definitions for cpu-detection 138* base implementations are located in `src/dsp/*.{h,cc}` with platform 139 specific optimizations in sub-folders 140* unit tests define `DISABLED_Speed` test(s) to allow timing of individual 141 functions 142 143#### Symbol reduction 144 145Based on the build configuration unneeded lesser optimizations are removed using 146a hierarchical include and define system. Each logical unit in `src/dsp` should 147include all platform specific headers in descending order to allow higher level 148optimizations to disable lower level ones. See `src/dsp/loop_filter.h` for an 149example. 150 151Each function receives a new define which can be checked in platform specific 152headers. The format is: `LIBGAV1_<Dsp-table>_FunctionName` or 153`LIBGAV1_<Dsp-table>_[sub-table-index1][...-indexN]`, e.g., 154`LIBGAV1_Dsp8bpp_AverageBlend`, 155`LIBGAV1_Dsp8bpp_TransformSize4x4_IntraPredictorDc`. The Dsp-table name is of 156the form `Dsp<bitdepth>bpp` e.g. `Dsp10bpp` for bitdepth == 10 (bpp stands for 157bits per pixel). The indices correspond to enum values used as lookups with 158leading 'k' removed. Platform specific headers then should first check if the 159symbol is defined and if not set the value to the corresponding 160`LIBGAV1_CPU_<arch>` value from `src/utils/cpu.h`. 161 162``` 163 #ifndef LIBGAV1_Dsp8bpp_TransformSize4x4_IntraPredictorDc 164 #define LIBGAV1_Dsp8bpp_TransformSize4x4_IntraPredictorDc LIBGAV1_CPU_SSE4_1 165 #endif 166``` 167 168Within each module the code should check if the symbol is defined to its 169specific architecture or forced via `LIBGAV1_ENABLE_ALL_DSP_FUNCTIONS` before 170defining the function. The `DSP_ENABLED_(8|10)BPP_*` macros are available to 171simplify this check for optimized code. 172 173``` 174 #if DSP_ENABLED_8BPP_SSE4_1(TransformSize4x4_IntraPredictorDc) 175 ... 176 177 // In unoptimized code use the following structure; there's no equivalent 178 // define for LIBGAV1_CPU_C as it would require duplicating the function 179 // defines used in optimized code for only a small benefit to this 180 // boilerplate. 181 #if LIBGAV1_ENABLE_ALL_DSP_FUNCTIONS 182 ... 183 #else // !LIBGAV1_ENABLE_ALL_DSP_FUNCTIONS 184 #ifndef LIBGAV1_Dsp8bpp_TransformSize4x4_IntraPredictorDcFill 185 ... 186``` 187 188## Bugs 189 190Please report all bugs to the issue tracker: 191https://issuetracker.google.com/issues/new?component=750480&template=1355007 192 193## Discussion 194 195Email: [email protected] 196 197Web: https://groups.google.com/forum/#!forum/gav1-devel 198