Add decoder controls for getting last quantizer.
Also adds --framestats=file.csv to aomdec that prints a CSV file with
frame size and frame QP.
Change-Id: I3b70c4b3df35d0b97bdd83cfc4631f096573b4a2
diff --git a/aomdec.c b/aomdec.c
index 026cb95..acfc7ce 100644
--- a/aomdec.c
+++ b/aomdec.c
@@ -97,6 +97,8 @@
ARG_DEF(NULL, "frame-buffers", 1, "Number of frame buffers to use");
static const arg_def_t md5arg =
ARG_DEF(NULL, "md5", 0, "Compute the MD5 sum of the decoded frame");
+static const arg_def_t framestatsarg =
+ ARG_DEF(NULL, "framestats", 1, "Output per-frame stats (.csv format)");
#if CONFIG_AOM_HIGHBITDEPTH
static const arg_def_t outbitdeptharg =
ARG_DEF(NULL, "output-bit-depth", 1, "Output bit-depth for decoded frames");
@@ -128,6 +130,7 @@
&scalearg,
&fb_arg,
&md5arg,
+ &framestatsarg,
&error_concealment,
&continuearg,
#if CONFIG_AOM_HIGHBITDEPTH
@@ -541,6 +544,8 @@
char outfile_name[PATH_MAX] = { 0 };
FILE *outfile = NULL;
+ FILE *framestats_file = NULL;
+
MD5Context md5_ctx;
unsigned char md5_digest[16];
@@ -567,9 +572,9 @@
die("Error: Unrecognized argument (%s) to --codec\n", arg.val);
} else if (arg_match(&arg, &looparg, argi)) {
// no-op
- } else if (arg_match(&arg, &outputfile, argi))
+ } else if (arg_match(&arg, &outputfile, argi)) {
outfile_pattern = arg.val;
- else if (arg_match(&arg, &use_yv12, argi)) {
+ } else if (arg_match(&arg, &use_yv12, argi)) {
use_y4m = 0;
flipuv = 1;
opt_yv12 = 1;
@@ -579,24 +584,31 @@
opt_i420 = 1;
} else if (arg_match(&arg, &rawvideo, argi)) {
use_y4m = 0;
- } else if (arg_match(&arg, &flipuvarg, argi))
+ } else if (arg_match(&arg, &flipuvarg, argi)) {
flipuv = 1;
- else if (arg_match(&arg, &noblitarg, argi))
+ } else if (arg_match(&arg, &noblitarg, argi)) {
noblit = 1;
- else if (arg_match(&arg, &progressarg, argi))
+ } else if (arg_match(&arg, &progressarg, argi)) {
progress = 1;
- else if (arg_match(&arg, &limitarg, argi))
+ } else if (arg_match(&arg, &limitarg, argi)) {
stop_after = arg_parse_uint(&arg);
- else if (arg_match(&arg, &skiparg, argi))
+ } else if (arg_match(&arg, &skiparg, argi)) {
arg_skip = arg_parse_uint(&arg);
- else if (arg_match(&arg, &postprocarg, argi))
+ } else if (arg_match(&arg, &postprocarg, argi)) {
postproc = 1;
- else if (arg_match(&arg, &md5arg, argi))
+ } else if (arg_match(&arg, &md5arg, argi)) {
do_md5 = 1;
- else if (arg_match(&arg, &summaryarg, argi))
+ } else if (arg_match(&arg, &framestatsarg, argi)) {
+ framestats_file = fopen(arg.val, "w");
+ if (!framestats_file) {
+ die("Error: Could not open --framestats file (%s) for writing.\n",
+ arg.val);
+ }
+ } else if (arg_match(&arg, &summaryarg, argi)) {
summary = 1;
- else if (arg_match(&arg, &threadsarg, argi))
+ } else if (arg_match(&arg, &threadsarg, argi)) {
cfg.threads = arg_parse_uint(&arg);
+ }
#if CONFIG_AV1_DECODER
else if (arg_match(&arg, &frameparallelarg, argi))
frame_parallel = 1;
@@ -756,6 +768,8 @@
frame_avail = 1;
got_data = 0;
+ if (framestats_file) fprintf(framestats_file, "bytes,qp\r\n");
+
/* Decode file */
while (frame_avail || got_data) {
aom_codec_iter_t iter = NULL;
@@ -781,6 +795,16 @@
if (!keep_going) goto fail;
}
+ if (framestats_file) {
+ int qp;
+ if (aom_codec_control(&decoder, AOMD_GET_LAST_QUANTIZER, &qp)) {
+ warn("Failed AOMD_GET_LAST_QUANTIZER: %s",
+ aom_codec_error(&decoder));
+ if (!keep_going) goto fail;
+ }
+ fprintf(framestats_file, "%d,%d\r\n", (int)bytes_in_buffer, qp);
+ }
+
aom_usec_timer_mark(&timer);
dx_time += aom_usec_timer_elapsed(&timer);
} else {
@@ -1017,6 +1041,8 @@
free(ext_fb_list.ext_fb);
fclose(infile);
+ if (framestats_file) fclose(framestats_file);
+
free(argv);
return ret;