Log in

View Full Version : dav1d accelerated AV1 decoder


Pages : 1 2 3 [4]

benwaggoner
14th February 2024, 20:19
RISC-V is interesting. It's starting to go into a lot of embedded things. License free (unlike ARM) and a very elegant architecture.

hajj_3
9th March 2024, 17:41
v1.4.1 'Road Runner':
--------------------------------

- Optimizations for 6tap filters for NEON (ARM)
- More RISC-V optimizations for itx (4x8, 8x4, 4x16, 16x4, 8x16, 16x8)
- Reduction of binary size on ARM64, ARM32 and RISC-V
- Fix out-of-bounds read in 8bpc SSE2/SSSE3 wiener_filter
- Msac optimizations

dapperdan
20th April 2024, 21:22
dav1d pushed as part of a Google update going out to Android 12+

https://twitter.com/videolan/status/1781025929659392360

Apps will still use the Google developed alternative libgav1 unless they opt in though.

Beelzebubu
22nd April 2024, 16:28
dav1d pushed as part of a Google update going out to Android 12+

https://twitter.com/videolan/status/1781025929659392360

Apps will still use the Google developed alternative libgav1 unless they opt in though.

See also: https://www.linkedin.com/feed/update/urn:li:activity:7186235577493544960/

"Apps need to opt into dav1d to benefit for now yet soon it will become the default av1 software decoder. "

benwaggoner
24th April 2024, 20:02
dav1d pushed as part of a Google update going out to Android 12+

https://twitter.com/videolan/status/1781025929659392360

Apps will still use the Google developed alternative libgav1 unless they opt in though.
The odds of Apple shipping someone else's precompiled binary in any of their OSes is very low these days. For security, portability, and optimization reasons.

They may leverage dav1d source code, but with their own tweaks and compile.

Ritsuka
24th April 2024, 20:47
Apple has been shipping dav1d for years. The arm64 version is compiled with pointer authentication codes enabled.

nevcairiel
24th April 2024, 21:27
The odds of Apple shipping someone else's precompiled binary in any of their OSes is very low these days. For security, portability, and optimization reasons.

They may leverage dav1d source code, but with their own tweaks and compile.

Why would anyone with a serious distribution ever ship someone elses binary for an open-source project, instead of just compiling it for your target? Am I missing context for this comment?

Obviously they compile their own. As does Google for Android. And Microsoft for Windows.

LigH
21st May 2024, 21:57
dav1d 1.4.1-66-g3623543 (https://www.mediafire.com/file/phu2u316bzqhb1c/dav1d_1.4.1-66-g3623543.7z/file) (MSYS2; MinGW32 / MinGW64: GCC 14.1.0)

hajj_3
25th May 2024, 19:31
Changes for 1.4.2 'Road Runner':
--------------------------------

1.4.2 is a small release of dav1d, improving notably ARM, AVX-512 and PowerPC
- AVX2 optimizations for 8-tap and new variants for 6-tap
- AVX-512 optimizations for 8-tap and new variants for 6-tap
- Improve entropy decoding on ARM64
- New ARM64 optimizations for convolutions based on DotProd extension
- New ARM64 optimizations for convolutions based on i8mm extension
- New ARM64 optimizations for subpel and prep filters for i8mm
- Misc improvements on existing ARM64 optimizations, notably for put/prep
- New PowerPC9 optimizations for loopfilter
- Support for macOS kperf API for benchmarking

Beelzebubu
26th May 2024, 14:01
The 6-tap optimizations for AVX2/512 were inspired by an earlier patch-set (provided by someone from Arm) doing the same on arm platforms. On both Arm (included in the previous release already) and x86 (in this release), on affected sequences (particularly these encoded using faster presets in encoders, which is what you'd find on Youtube etc.) this can provide a ~10% overall performance improvement. Pretty spectacular at this stage of dav1d's life cycle.

oibaf
26th May 2024, 17:22
Interesting. Is there a recent comparison of AV1 decoders? I remember there were in the past.

birdie
27th May 2024, 15:20
Interesting. Is there a recent comparison of AV1 decoders? I remember there were in the past.

Everything but dav1d is dead slow.

BlueSwordM
15th June 2024, 19:07
The main reason libgav1 existed is that Google temporarily suffered from the NIH (Not In Here) syndrome.
Some stuff from libgav1 made its way into dav1d and everything else is now history :)

hajj_3
20th January 2025, 17:23
Changes for 1.5.1 'Sonic':
--------------------------

1.5.1 is a minor release of dav1d, focusing on optimizations and stack reduction:

- Rewrite of the looprestoration (SGR, wiener) to reduce stack usage
- Rewrite of {put,prep}_scaled functions

Now, the required stack space for dav1d should be: 62 KB on x86_64 and
58KB on arm and aarch64.

- Improvements on the SSSE3 SGR
- Improvements on ARM32/ARM64 looprestoration optimizations
- RISC-V: blend optimizations for high bitdepth
- Power9: blend optimizations for 8bpc
- Port RISC-V to POSIX/non-Linux OS
- AArch64: Add Neon implementation of load_tmvs
- Fix a rare, but possible deadlock, in flush()

benwaggoner
23rd January 2025, 20:37
Everything but dav1d is dead slow.
A fine illustration of how much low-level optimization can improve signal processing performance. We can still see 4x improvements between "a lot of optimization" and "great optimization."

Z2697
3rd May 2026, 20:09
-DCONFIG_8BPC -DCONFIG_16BPC -DBITDEPTH=8

?????
Are you trying to be smarter than the build system (but failed).

Jamaika
3rd May 2026, 21:11
?????
Are you trying to be smarter than the build system (but failed).
I wanted to use an 8-bit and a 10/12/14/16-bit decoder. What's so strange about that?

After the latest patch, it stopped working.
https://code.videolan.org/videolan/dav1d/-/commit/f995e1fbf9379027367a93aafd2b5711ba76f81e

Z2697
4th May 2026, 01:43
I wanted to use an 8-bit and a 10/12/14/16-bit decoder. What's so strange about that?

After the latest patch, it stopped working.
https://code.videolan.org/videolan/dav1d/-/commit/f995e1fbf9379027367a93aafd2b5711ba76f81e

Because they should be defined by build system as needed, not you.
No that commit has nothing to do with this error.
The relative code that gets triggered by your erroneous use exists since 402b54fcaecd424726b3f1292b4fea3c5b1d8e35 Tue Feb 1 17:44:26 2022 +0100.
You try to manually grind through the building process without using the official build system, that's very... endeavourous, but please keep it to yourself.

Jamaika
4th May 2026, 06:44
So there will only be an 8-bit decoder. -DCONFIG_8BPC -DBITDEPTH=8
Overall, things are getting interesting. Two decoders, one 8-bit and one 16-bit, and two decoders, one av1 and one av2, meaning four plugins. It'll be interesting to see how they share common functions.

rwill
4th May 2026, 07:19
...


This is so amazing. Jamaika copy/pasted some compile error without ANY hints or comment of why and what he wants and you narrowed it down to him wanting to do strange things again.

I wish I could read minds like that.

Jamaika
4th May 2026, 09:07
I was surprised it worked before. I see this interesting thread. As far as I'm concerned, there are no programming enthusiasts here, only weirdos, trolls, or their own advertising geeks. The rest are idiots. Your comment contributed nothing. I didn't want to register on another dav1d page. The question remains: what's the purpose of CONFIG_16BPC? Maybe delete it.

Z2697
4th May 2026, 16:23
So there will only be an 8-bit decoder. -DCONFIG_8BPC -DBITDEPTH=8
Overall, things are getting interesting. Two decoders, one 8-bit and one 16-bit, and two decoders, one av1 and one av2, meaning four plugins. It'll be interesting to see how they share common functions.

NO.

Both CONFIG_8BPC and CONFIG_16BPC are defined in the generated config.h file as 1 in a normal meson build.

BITDEPTH is supplied by the build comamnd(s) in the generated ninja build file but it is not defined for this file.

For (some of) other files, same files with different BITDEPTH are defined and compiled multiple times.

Use the goddayuum build system.
Or at least, learn from it, if you insist on grinding.

foxyshadis
5th May 2026, 10:27
Jamaika's build is pointlessly manual, but the highlighted defines are not the source of his problem, since it generally actually did work for some time. I strongly suspect there's either been a bad merge based on something he edited in a source file, since it builds fine by the official supported method, or that a new define was added somewhere along the way and is only now being used in a way that breaks the build otherwise. Which would simply not be a problem if you re-ran meson before every build.

Jamaika, unless you have a compelling reason to post a problem, like a major bug you've spotted, please don't post it here. Fix your build system on your own, instead of trying to make it someone else's problem yet again. Actually don't even post major bugs here until you've reported them on videolan as well, since it does no one any good to hear about them here when Videolan is the only one who can do anything about them. And if you don't want to sign up for the official home of the software, I don't know what to tell you, just don't pretend this is a proxy for it.

Z2697
5th May 2026, 11:37
Jamaika's build is pointlessly manual, but the highlighted defines are not the source of his problem, since it generally actually did work for some time.

I actually tried that define (BITDEPTH) with the "initial commit" I mentioned and it fails.
So the reason it had worked is a mystery. Probably Jamaika's process actually changed.

CONFIG_8BPC and CONFIG_16BPC don't actually matter since they are always defined as 1 in config.h (in default setting), but that's generated by meson.
This header was never there unless meson is ran, and source files include config.h. How Jamaika deals with it is another question...

Beelzebubu
15th June 2026, 01:34
The question remains: what's the purpose of CONFIG_16BPC? Maybe delete it.

The idea of CONFIG_xBPC is to be able to generate a build of dav1d that supports only high-bitdepth ("16bpc") or only low-bitdepth ("8bpc") instead of one that supports both. Internally, what will happen (in e.g. the case where you want only a LBD-decoder) is that the build disables building all 16bpc-related objects, and all templated build files (which are normally compiled twice; once for 8bpc and once for 16bpc) are now only built once, for the desired bitdepth.

This worked at some point and should still work, I thought we had CI tests for that, but maybe it broke. If it's broken, please submit a bug report on dav1d's gitlab.

[edit] -DBITDEPTH=x is how the templating works internally. You should not define -DBITDEPTH by yourself, it will conflict with how the build uses this define.

Jamaika
15th June 2026, 06:18
The idea of CONFIG_xBPC is to be able to generate a build of dav1d that supports only high-bitdepth ("16bpc") or only low-bitdepth ("8bpc") instead of one that supports both. Internally, what will happen (in e.g. the case where you want only a LBD-decoder) is that the build disables building all 16bpc-related objects, and all templated build files (which are normally compiled twice; once for 8bpc and once for 16bpc) are now only built once, for the desired bitdepth.

This worked at some point and should still work, I thought we had CI tests for that, but maybe it broke. If it's broken, please submit a bug report on dav1d's gitlab.

[edit] -DBITDEPTH=x is how the templating works internally. You should not define -DBITDEPTH by yourself, it will conflict with how the build uses this define.

First of all, I can't log in to Videolan. This is apparently the only mirror. Apparently I'm not an employee.

This split was suggested for dav1d. Logically, I was adding 16-bit. What does only 8-bit mean? For example, I wanted to downscale 10/12-bit video to 8-bit. It turns out that this is an error in my reasoning.

This is a strange error that has been occurring for years when I've been manually merging for both 8bit and 16bit, for dav1d and dav2d. In dav2d, these errors are more common for 16bit.
ts->frame_thread[p].cf = f->frame_thread.cf ?
(coef*)((uint8_t*)f->frame_thread.cf +
(((size_t)tile_start_off * size_mul[0]) >> !f->seq_hdr->hbd)) :
NULL;
Why should I annoy the developers that I don't use cmake? That's an automatic ban. It is what it is and sometimes I complain.

This isn't possible for dav2d. It only theoretically supports 8-bit. Furthermore, the description states that the AVM codec is 10-bit. Inputdepthinternal is always 10bit. Why would anyone need an 8-bit decoder?

And one more thing for the future. If someone wanted to add two decoders, one 8-bit and one 16-bit, to FFMPEG, it turns out they share common functions.

Viewing AOM HDR video is unreal by dav1d 8bit in ffmpeg.
https://pixeldrain.com/u/WKoG8vZc

Beelzebubu
15th June 2026, 12:15
First of all, I can't log in to Videolan. This is apparently the only mirror. Apparently I'm not an employee.

If your account doesn't work, go on IRC and ask on the relevant IRC channels, e.g. #videolan (on Libera).

Videolan is not for employees only.

This split was suggested for dav1d. Logically, I was adding 16-bit.

I don't know what to make of this. dav1d already supports high-bitdepth (10/12-bit) decoding. There is no 16bit in AV1.

What does only 8-bit mean? For example, I wanted to downscale 10/12-bit video to 8-bit. It turns out that this is an error in my reasoning.

If your AV1 video is 10/12bit, and you want to decode it using dav1d, it will only use the high-bitdepth code path. Whatever you do after that with this video in your processing pipeline (such as downscaling to 8bit) is completely independent of AV1 decoding. dav1d plays no part in that. dav1d has no built-in up/down-scaler/sampler or any other processing frameworks not directly part of AV1 decoding.

This is a strange error that has been occurring for years when I've been manually merging for both 8bit and 16bit, for dav1d and dav2d. In dav2d, these errors are more common for 16bit.
ts->frame_thread[p].cf = f->frame_thread.cf ?
(coef*)((uint8_t*)f->frame_thread.cf +
(((size_t)tile_start_off * size_mul[0]) >> !f->seq_hdr->hbd)) :
NULL;
Why should I annoy the developers that I don't use cmake? That's an automatic ban. It is what it is and sometimes I complain.

You should learn to be more utalitarian in your complaining.

In the end, if you want a custom build script, you'll still have to grab the relevant info from `meson.build`. You will find 5 lists of object files for 4 types of source files:
- objects that are built from source files, and that are specific to low-bitdepth decoding only. These will be built if CONFIG_8BPC is set.
- objects that are built from source files, and that are specific to high-bitdepth decoding only. These will be built if CONFIG_16BPC is set.
- objects that are built from source files, common to all decodeable bitdepths.
- objects that are built from *templated* source files. These will be built if CONFIG_8BPC is set, and when building the templated source files, they will define -DBITDEPTH=16 or -DBITDEPTH=8 to generate either low-bitdepth object files or high-bitdepth object files. The object files generated from these source files will get a 8bpc or 16bpc suffix, e.g. recon_tmpl.c becomes recon_8bpc.o or recon_16bpc.o.

If you want to use your own build system, just re-create this pattern. For your convenience, we have named all source files that are templated something like x_tmpl.c (e.g. recon_tmpl.c). This way, it should be easy to figure out which files should be with -DBITDEPTH=x and which files don't need that. We know of several people using this pattern-matching system. (This doesn't work for unit tests.) The final library built is a collection of object files to support whatever bitdepth(s) you desired, this can be low-bitdepth or high-bitdepth only, but by default it's (obviously) both.

This isn't possible for dav2d.

dav2d uses the same general rules for the build system, but we have not tested these kind of build rules yet, so you'll need more expertise to get this to work.

It only theoretically supports 8-bit.

This is obviously not true.

Furthermore, the description states that the AVM codec is 10-bit. Inputdepthinternal is always 10bit. Why would anyone need an 8-bit decoder?

To be faster. If your content is low-bitdepth, your pixels fit in 8bit types. This means that an AVX2 register (32bytes) can contain 32pixels. If we used a high-bitdepth codepath, the same AVX2 register would only contain 32bytes=16pixels. Do the math on expected decoding speed.

And one more thing for the future. If someone wanted to add two decoders, one 8-bit and one 16-bit, to FFMPEG, it turns out they share common functions.

The decoder - by default - supports both bitdepths, so the use case of 2 decoders, one for each bitdepth, is not one that we see as being necessary and is therefore not supported.

Z2697
15th June 2026, 12:26
Jamaika is usually hard to understand...
But that "no programming enthusiasts" sentence is, well, pretty clear.
How so?

Jamaika
15th June 2026, 14:08
I don't know what to make of this. dav1d already supports high-bitdepth (10/12-bit) decoding. There is no 16bit in AV1.
When calling the reference encoder, --qp shall be used to specify the qindex directly within the
following valid range:
● 8 bit: [0, 255]
● 10 bit: [-48, 255]
● 12 bit: [-96, 255]
Encoder internally will add a proper offset (48 for 10 bit and 96 for 12 bit) to get the final qindex
encoded in the bitstream.

https://aomedia.org/docs/CWG-F384o_AV2_CTC_v8.pdf
Honestly, I don't know. The AV1 decoder has numerous fixes. Currently, the AV1 decoder doesn't show information about what's being output. I don't know if it's a 10/12-bit movie in an 8-bit container.
I know that for AV2 12bit input gives 12bit output and I can confirm it using ffmpeg.
Input #0, image2, from 'output_avm_12bit.av2':
Duration: 00:00:00.04, start: 0.000000, bitrate: 1192055 kb/s
Stream #0:0: Video: av2 (libavm-av2), yuv444p12le(tv), 4000x3000 [SAR 1:1 DAR 4:3], 25 fps, 25 tbr, 25 tbn
9.04 M-V: 0.000 fd= 0 aq= 0KB vq= 0KB sq= 0B

Jamaika
15th June 2026, 14:11
If your AV1 video is 10/12bit, and you want to decode it using dav1d, it will only use the high-bitdepth code path. Whatever you do after that with this video in your processing pipeline (such as downscaling to 8bit) is completely independent of AV1 decoding. dav1d plays no part in that. dav1d has no built-in up/down-scaler/sampler or any other processing frameworks not directly part of AV1 decoding.
This is understandable.

Jamaika
15th June 2026, 14:14
In the end, if you want a custom build script, you'll still have to grab the relevant info from `meson.build`. You will find 5 lists of object files for 4 types of source files:
- objects that are built from source files, and that are specific to low-bitdepth decoding only. These will be built if CONFIG_8BPC is set.
- objects that are built from source files, and that are specific to high-bitdepth decoding only. These will be built if CONFIG_16BPC is set.
- objects that are built from source files, common to all decodeable bitdepths.
- objects that are built from *templated* source files. These will be built if CONFIG_8BPC is set, and when building the templated source files, they will define -DBITDEPTH=16 or -DBITDEPTH=8 to generate either low-bitdepth object files or high-bitdepth object files. The object files generated from these source files will get a 8bpc or 16bpc suffix, e.g. recon_tmpl.c becomes recon_8bpc.o or recon_16bpc.o.

If you want to use your own build system, just re-create this pattern. For your convenience, we have named all source files that are templated something like x_tmpl.c (e.g. recon_tmpl.c). This way, it should be easy to figure out which files should be with -DBITDEPTH=x and which files don't need that. We know of several people using this pattern-matching system. (This doesn't work for unit tests.) The final library built is a collection of object files to support whatever bitdepth(s) you desired, this can be low-bitdepth or high-bitdepth only, but by default it's (obviously) both.
I already know that. Unfortunately, gcc won't create a dav1d or dav2d decoder for CONFIG_8BPC. I had to add the above patch.

Jamaika
15th June 2026, 14:17
The decoder - by default - supports both bitdepths, so the use case of 2 decoders, one for each bitdepth, is not one that we see as being necessary and is therefore not supported.
For AV1, perhaps yes, if it's not 10/12 bit.
For AV2, that's a problem in my understanding.

Edit:
AV1 can be 10/12bit:
ffmpeg_vulkan_avx2.exe -loglevel warning -y -i "input.mp4" -frames:v 100 -vf "scale=1280:720,format=yuv420p12le" -f yuv4mpegpipe -strict -1 __REF.y4m
aomenc.exe --verbose --threads=16 --cpu-used=8 --end-usage=cbr --target-bitrate=3000 -o __AV1.webm __REF.y4m

Input #0, ivf, from '__AV1.ivf': 0KB vq= 0KB sq= 0B
Duration: 00:00:01.67, start: 0.000000, bitrate: 2497 kb/s
Stream #0:0: Video: av1 (libdav1d) (Professional) (AV01 / 0x31305641), yuv420p12le(tv), 1280x720 [SAR 1:1 DAR 16:9], 60 tbr, 60 tbn

To my surprise, the old dav1d 1.5.0-40ff2a1 version in ffmpeg from two years ago played the file without any problems. It wasn't pure dav1d 8bit.
https://www.sendspace.com/file/clays8

Beelzebubu
15th June 2026, 14:24
I already know that. Unfortunately, gcc won't create a dav1d or dav2d decoder for CONFIG_8BPC.

I just double checked to make sure, and we do indeed have bitdepth-specific builds as part of our CI (https://code.videolan.org/videolan/dav1d/-/blob/master/.gitlab-ci.yml?ref_type=heads#L175). So any problem is in your build system alone.

Let's be practical here: what is the *actual* build step (e.g. what is the full gcc commandline invocation) that is failing in your custom build process, and what is the *full and uncut* error message you're getting? I don't mind helping you along in your journey of using dav1d, but I need a lot more information than the few fragments you've been sharing so far.

Z2697
15th June 2026, 16:25
Somehow I feel that if you are hardcore enough to bypass the build system then those problems should be nothing...
Like, where's the learning curve?