ref: 6fd4013ae95649c7cb40337cb2e9efa7dd2e404d
parent: 285d1b7641df768621b57787a7ae3c20d6f6794d
author: Janne Grunau <[email protected]>
date: Tue Oct 30 19:50:43 EDT 2018
dav1d: add --verify option to verify decoding results Will be used for regression tests.
--- a/tools/dav1d.c
+++ b/tools/dav1d.c
@@ -167,7 +167,10 @@
if (out) {
if (!cli_settings.quiet && istty)
fprintf(stderr, "\n");
- output_close(out);
+ if (cli_settings.verify)
+ res |= output_verify(out, cli_settings.verify);
+ else
+ output_close(out);
} else {
fprintf(stderr, "No data decoded\n");
res = 1;
--- a/tools/dav1d_cli_parse.c
+++ b/tools/dav1d_cli_parse.c
@@ -47,6 +47,7 @@
ARG_MUXER,
ARG_FRAME_THREADS,
ARG_TILE_THREADS,
+ ARG_VERIFY,
};
static const struct option long_opts[] = {
@@ -60,6 +61,7 @@
{ "skip", 1, NULL, 's' },
{ "framethreads", 1, NULL, ARG_FRAME_THREADS },
{ "tilethreads", 1, NULL, ARG_TILE_THREADS },
+ { "verify", 1, NULL, ARG_VERIFY },
{ NULL, 0, NULL, 0 },
};
@@ -83,7 +85,8 @@
" --skip/-s $num: skip decoding of the first $num frames\n"
" --version/-v: print version and exit\n"
" --framethreads $num: number of frame threads (default: 1)\n"
- " --tilethreads $num: number of tile threads (default: 1)\n");
+ " --tilethreads $num: number of tile threads (default: 1)\n"
+ " --verify $md5: verify decoded md5. implies --muxer md5, no output\n");
exit(1);
}
@@ -153,6 +156,9 @@
lib_settings->n_tile_threads =
parse_unsigned(optarg, ARG_TILE_THREADS, argv[0]);
break;
+ case ARG_VERIFY:
+ cli_settings->verify = optarg;
+ break;
case 'v':
fprintf(stderr, "%s\n", dav1d_version());
exit(0);
@@ -159,6 +165,17 @@
default:
break;
}
+ }
+
+ if (cli_settings->verify) {
+ if (cli_settings->outputfile)
+ usage(argv[0], "Verification (--verify) requires output file (-o/--output) to not set");
+ if (cli_settings->muxer && !strcmp(cli_settings->muxer, "md5"))
+ usage(argv[0], "Verification (--verify) requires the md5 muxer (--muxer md5)");
+
+ cli_settings->outputfile = "-";
+ if (!cli_settings->muxer)
+ cli_settings->muxer = "md5";
}
if (!cli_settings->inputfile)
--- a/tools/dav1d_cli_parse.h
+++ b/tools/dav1d_cli_parse.h
@@ -35,6 +35,7 @@
const char *inputfile;
const char *demuxer;
const char *muxer;
+ const char *verify;
unsigned limit, skip;
int quiet;
} CLISettings;
--- a/tools/output/md5.c
+++ b/tools/output/md5.c
@@ -190,7 +190,7 @@
return 0;
}
-static void md5_close(MD5Context *const md5) {
+static void md5_finish(MD5Context *const md5) {
static const uint8_t bit[2] = { 0x80, 0x00 };
uint64_t len = md5->len << 3;
@@ -198,6 +198,10 @@
while ((md5->len & 63) != 56)
md5_update(md5, &bit[1], 1);
md5_update(md5, (uint8_t *) &len, 8);
+}
+
+static void md5_close(MD5Context *const md5) {
+ md5_finish(md5);
for (int i = 0; i < 4; i++)
fprintf(md5->f, "%2.2x%2.2x%2.2x%2.2x",
md5->abcd[i] & 0xff,
@@ -210,6 +214,29 @@
fclose(md5->f);
}
+static int md5_verify(MD5Context *const md5, const char *const md5_str) {
+ md5_finish(md5);
+
+ if (strlen(md5_str) < 32)
+ return 0;
+
+ const char *p = md5_str;
+ unsigned abcd[4] = { 0 };
+ char t[3] = { 0 };
+ for (int i = 0; i < 4; i++) {
+ for (int j = 0; j < 4; j++) {
+ unsigned val;
+ char *ignore;
+ memcpy(t, p, 2);
+ p += 2;
+ val = strtoul(t, &ignore, 16);
+ abcd[i] |= val << (8 * j);
+ }
+ }
+
+ return memcmp(abcd, md5->abcd, sizeof(abcd));
+}
+
const Muxer md5_muxer = {
.priv_data_size = sizeof(MD5Context),
.name = "md5",
@@ -217,4 +244,5 @@
.write_header = md5_open,
.write_picture = md5_write,
.write_trailer = md5_close,
+ .verify = md5_verify,
};
--- a/tools/output/muxer.h
+++ b/tools/output/muxer.h
@@ -39,6 +39,14 @@
const Dav1dPictureParameters *p, const unsigned fps[2]);
int (*write_picture)(MuxerPriv *ctx, Dav1dPicture *p);
void (*write_trailer)(MuxerPriv *ctx);
+ /**
+ * Verifies the muxed data (for example in the md5 muxer). Replaces write_trailer.
+ *
+ * @param hash_string Muxer specific reference value.
+ *
+ * @return 0 on success.
+ */
+ int (*verify)(MuxerPriv *ctx, const char *hash_string);
} Muxer;
#endif /* __DAV1D_OUTPUT_MUXER_H__ */
--- a/tools/output/output.c
+++ b/tools/output/output.c
@@ -142,3 +142,11 @@
ctx->impl->write_trailer(ctx->data);
free(ctx);
}
+
+int output_verify(MuxerContext *const ctx, const char *const md5_Str) {
+ int res = 0;
+ if (ctx->impl->verify)
+ res = ctx->impl->verify(ctx->data, md5_Str);
+ free(ctx);
+ return res;
+}
--- a/tools/output/output.h
+++ b/tools/output/output.h
@@ -37,5 +37,13 @@
const Dav1dPictureParameters *p, const unsigned fps[2]);
int output_write(MuxerContext *ctx, Dav1dPicture *pic);
void output_close(MuxerContext *ctx);
+/**
+ * Verifies the muxed data (for example in the md5 muxer). Replaces output_close.
+ *
+ * @param hash_string Muxer specific reference value.
+ *
+ * @return 0 on success.
+ */
+int output_verify(MuxerContext *ctx, const char *hash_string);
#endif /* __DAV1D_OUTPUT_OUTPUT_H__ */