diff options
author | Victorien Le Couviour--Tuffet <victorien@videolan.org> | 2021-10-27 17:14:40 +0300 |
---|---|---|
committer | Victorien Le Couviour--Tuffet <victorien@videolan.org> | 2021-10-29 23:18:05 +0300 |
commit | 8e6d5214a356dfc91c09468ac7473d8a66bf26cd (patch) | |
tree | 91331db1718f001a10d145dcd50d2a4493aaa300 /tools | |
parent | 8c94f95c8750c0d805e1a666d302756006554597 (diff) |
CI: Add tests for negative stride
Diffstat (limited to 'tools')
-rw-r--r-- | tools/dav1d.c | 46 | ||||
-rw-r--r-- | tools/dav1d_cli_parse.c | 9 | ||||
-rw-r--r-- | tools/dav1d_cli_parse.h | 1 |
3 files changed, 55 insertions, 1 deletions
diff --git a/tools/dav1d.c b/tools/dav1d.c index bb1f4fd..5087180 100644 --- a/tools/dav1d.c +++ b/tools/dav1d.c @@ -29,6 +29,7 @@ #include "vcs_version.h" #include "cli_config.h" +#include <assert.h> #include <errno.h> #include <inttypes.h> #include <math.h> @@ -139,6 +140,47 @@ static void print_stats(const int istty, const unsigned n, const unsigned num, fputs(buf, stderr); } +static int picture_alloc(Dav1dPicture *const p, void *const _) { + const int hbd = p->p.bpc > 8; + const int aligned_w = (p->p.w + 127) & ~127; + const int aligned_h = (p->p.h + 127) & ~127; + const int has_chroma = p->p.layout != DAV1D_PIXEL_LAYOUT_I400; + const int ss_ver = p->p.layout == DAV1D_PIXEL_LAYOUT_I420; + const int ss_hor = p->p.layout != DAV1D_PIXEL_LAYOUT_I444; + ptrdiff_t y_stride = aligned_w << hbd; + ptrdiff_t uv_stride = has_chroma ? y_stride >> ss_hor : 0; + /* Due to how mapping of addresses to sets works in most L1 and L2 cache + * implementations, strides of multiples of certain power-of-two numbers + * may cause multiple rows of the same superblock to map to the same set, + * causing evictions of previous rows resulting in a reduction in cache + * hit rate. Avoid that by slightly padding the stride when necessary. */ + if (!(y_stride & 1023)) + y_stride += DAV1D_PICTURE_ALIGNMENT; + if (!(uv_stride & 1023) && has_chroma) + uv_stride += DAV1D_PICTURE_ALIGNMENT; + p->stride[0] = -y_stride; + p->stride[1] = -uv_stride; + const size_t y_sz = y_stride * aligned_h; + const size_t uv_sz = uv_stride * (aligned_h >> ss_ver); + const size_t pic_size = y_sz + 2 * uv_sz; + + uint8_t *const buf = malloc(pic_size + DAV1D_PICTURE_ALIGNMENT * 2); + if (!buf) return DAV1D_ERR(ENOMEM); + p->allocator_data = buf; + + const ptrdiff_t align_m1 = DAV1D_PICTURE_ALIGNMENT - 1; + uint8_t *const data = (uint8_t *)(((ptrdiff_t)buf + align_m1) & ~align_m1); + p->data[0] = data + y_sz - y_stride; + p->data[1] = has_chroma ? data + y_sz + uv_sz * 1 - uv_stride : NULL; + p->data[2] = has_chroma ? data + y_sz + uv_sz * 2 - uv_stride : NULL; + + return 0; +} + +static void picture_release(Dav1dPicture *const p, void *const _) { + free(p->allocator_data); +} + int main(const int argc, char *const *const argv) { const int istty = isatty(fileno(stderr)); int res = 0; @@ -162,6 +204,10 @@ int main(const int argc, char *const *const argv) { } parse(argc, argv, &cli_settings, &lib_settings); + if (cli_settings.neg_stride) { + lib_settings.allocator.alloc_picture_callback = picture_alloc; + lib_settings.allocator.release_picture_callback = picture_release; + } if ((res = input_open(&in, cli_settings.demuxer, cli_settings.inputfile, diff --git a/tools/dav1d_cli_parse.c b/tools/dav1d_cli_parse.c index ab38400..7b24aa4 100644 --- a/tools/dav1d_cli_parse.c +++ b/tools/dav1d_cli_parse.c @@ -58,6 +58,7 @@ enum { ARG_ALL_LAYERS, ARG_SIZE_LIMIT, ARG_CPU_MASK, + ARG_NEG_STRIDE, }; static const struct option long_opts[] = { @@ -80,6 +81,7 @@ static const struct option long_opts[] = { { "alllayers", 1, NULL, ARG_ALL_LAYERS }, { "sizelimit", 1, NULL, ARG_SIZE_LIMIT }, { "cpumask", 1, NULL, ARG_CPU_MASK }, + { "negstride", 0, NULL, ARG_NEG_STRIDE }, { NULL, 0, NULL, 0 }, }; @@ -130,7 +132,9 @@ static void usage(const char *const app, const char *const reason, ...) { " --alllayers $num: output all spatial layers of a scalable AV1 bitstream (default: 1)\n" " --sizelimit $num: stop decoding if the frame size exceeds the specified limit\n" " --verify $md5: verify decoded md5. implies --muxer md5, no output\n" - " --cpumask $mask: restrict permitted CPU instruction sets (0" ALLOWED_CPU_MASKS "; default: -1)\n"); + " --cpumask $mask: restrict permitted CPU instruction sets (0" ALLOWED_CPU_MASKS "; default: -1)\n" + " --negstride: use negative picture strides\n" + " this is mostly meant as a developer option\n"); exit(1); } @@ -338,6 +342,9 @@ void parse(const int argc, char *const *const argv, dav1d_set_cpu_flags_mask(parse_enum(optarg, cpu_mask_tbl, ARRAY_SIZE(cpu_mask_tbl), ARG_CPU_MASK, argv[0])); break; + case ARG_NEG_STRIDE: + cli_settings->neg_stride = 1; + break; default: usage(argv[0], NULL); } diff --git a/tools/dav1d_cli_parse.h b/tools/dav1d_cli_parse.h index 11e88e1..50cfeb8 100644 --- a/tools/dav1d_cli_parse.h +++ b/tools/dav1d_cli_parse.h @@ -46,6 +46,7 @@ typedef struct { } realtime; double realtime_fps; unsigned realtime_cache; + int neg_stride; } CLISettings; void parse(const int argc, char *const *const argv, |