aom_entropy_optimizer.c 28.9 KB
Newer Older
Yue Chen's avatar
Yue Chen committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
/*
 * Copyright (c) 2017, Alliance for Open Media. All rights reserved
 *
 * This source code is subject to the terms of the BSD 2 Clause License and
 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
 * was not distributed with this source code in the LICENSE file, you can
 * obtain it at www.aomedia.org/license/software. If the Alliance for Open
 * Media Patent License 1.0 was not distributed with this source code in the
 * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
 */

// This tool is a gadget for offline probability training.
// A binary executable aom_entropy_optimizer will be generated in tools/. It
// parses a binary file consisting of counts written in the format of
15
16
17
// FRAME_COUNTS in entropymode.h, and computes optimized probability tables
// and CDF tables, which will be written to a new c file optimized_probs.c
// according to format in the codebase.
Yue Chen's avatar
Yue Chen committed
18
19
20
21
22
23
24
25
26
27
28
29
30
//
// Command line: ./aom_entropy_optimizer [directory of the count file]
//
// The input file can either be generated by encoding a single clip by
// turning on entropy_stats experiment, or be collected at a larger scale at
// which a python script which will be provided soon can be used to aggregate
// multiple stats output.

#include <assert.h>
#include <stdio.h>
#include "./aom_config.h"
#include "av1/common/entropymode.h"

31
32
33
const aom_tree_index av1_intra_mode_tree[TREE_SIZE(INTRA_MODES)] = {
  -DC_PRED,
  2, /* 0 = DC_NODE */
Urvang Joshi's avatar
Urvang Joshi committed
34
35
  -PAETH_PRED,
  4, /* 1 = PAETH_NODE */
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
  -V_PRED,
  6, /* 2 = V_NODE */
  8,
  12, /* 3 = COM_NODE */
  -H_PRED,
  10, /* 4 = H_NODE */
  -D135_PRED,
  -D117_PRED, /* 5 = D135_NODE */
  -D45_PRED,
  14, /* 6 = D45_NODE */
  -D63_PRED,
  16, /* 7 = D63_NODE */
  -D153_PRED,
  18, /* 8 = D153_NODE */
  -D207_PRED,
  20, /* 9 = D207_NODE */
  -SMOOTH_PRED,
  22, /* 10 = SMOOTH_NODE */
  -SMOOTH_V_PRED,
  -SMOOTH_H_PRED /* 11 = SMOOTH_V_NODE */
};

Yue Chen's avatar
Yue Chen committed
58
59
60
61
62
63
#define SPACES_PER_TAB 2

typedef unsigned int aom_count_type;
// A log file recording parsed counts
static FILE *logfile;  // TODO(yuec): make it a command line option

64
65
66
67
68
69
70
static INLINE aom_prob get_binary_prob_new(unsigned int n0, unsigned int n1) {
  // The "+1" will prevent this function from generating extreme probability
  // when both n0 and n1 are small
  const unsigned int den = n0 + 1 + n1 + 1;
  return get_prob(n0 + 1, den);
}

Yue Chen's avatar
Yue Chen committed
71
// Optimized probabilities will be stored in probs[].
72
73
74
75
static unsigned int optimize_tree_probs(const aom_tree_index *tree,
                                        unsigned int idx,
                                        const unsigned int *counts,
                                        aom_prob *probs) {
Yue Chen's avatar
Yue Chen committed
76
77
78
79
80
81
  const int l = tree[idx];
  const unsigned int left_count =
      (l <= 0) ? counts[-l] : optimize_tree_probs(tree, l, counts, probs);
  const int r = tree[idx + 1];
  const unsigned int right_count =
      (r <= 0) ? counts[-r] : optimize_tree_probs(tree, r, counts, probs);
82
  probs[idx >> 1] = get_binary_prob_new(left_count, right_count);
Yue Chen's avatar
Yue Chen committed
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
  return left_count + right_count;
}

static int parse_stats(aom_count_type **ct_ptr, FILE *const probsfile, int tabs,
                       int dim_of_cts, int *cts_each_dim,
                       const aom_tree_index *tree, int flatten_last_dim) {
  if (dim_of_cts < 1) {
    fprintf(stderr, "The dimension of a counts vector should be at least 1!\n");
    return 1;
  }
  if (dim_of_cts == 1) {
    const int total_modes = cts_each_dim[0];
    aom_count_type *counts1d = *ct_ptr;
    aom_prob *probs = aom_malloc(sizeof(*probs) * (total_modes - 1));

    if (probs == NULL) {
      fprintf(stderr, "Allocating prob array failed!\n");
      return 1;
    }

    (*ct_ptr) += total_modes;
    if (tree != NULL) {
      optimize_tree_probs(tree, 0, counts1d, probs);
    } else {
      assert(total_modes == 2);
108
      probs[0] = get_binary_prob_new(counts1d[0], counts1d[1]);
Yue Chen's avatar
Yue Chen committed
109
110
111
    }
    if (tabs > 0) fprintf(probsfile, "%*c", tabs * SPACES_PER_TAB, ' ');
    for (int k = 0; k < total_modes - 1; ++k) {
112
113
114
115
      if (k == total_modes - 2)
        fprintf(probsfile, " %3d ", probs[k]);
      else
        fprintf(probsfile, " %3d,", probs[k]);
Yue Chen's avatar
Yue Chen committed
116
117
118
119
120
121
122
      fprintf(logfile, "%d ", counts1d[k]);
    }
    fprintf(logfile, "%d\n", counts1d[total_modes - 1]);
  } else if (dim_of_cts == 2 && flatten_last_dim) {
    assert(cts_each_dim[1] == 2);

    for (int k = 0; k < cts_each_dim[0]; ++k) {
123
124
      if (k == cts_each_dim[0] - 1) {
        fprintf(probsfile, " %3d ",
125
                get_binary_prob_new((*ct_ptr)[0], (*ct_ptr)[1]));
126
127
      } else {
        fprintf(probsfile, " %3d,",
128
                get_binary_prob_new((*ct_ptr)[0], (*ct_ptr)[1]));
129
      }
Yue Chen's avatar
Yue Chen committed
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
      fprintf(logfile, "%d %d\n", (*ct_ptr)[0], (*ct_ptr)[1]);
      (*ct_ptr) += 2;
    }
  } else {
    for (int k = 0; k < cts_each_dim[0]; ++k) {
      int tabs_next_level;
      if (dim_of_cts == 2 || (dim_of_cts == 3 && flatten_last_dim)) {
        fprintf(probsfile, "%*c{", tabs * SPACES_PER_TAB, ' ');
        tabs_next_level = 0;
      } else {
        fprintf(probsfile, "%*c{\n", tabs * SPACES_PER_TAB, ' ');
        tabs_next_level = tabs + 1;
      }
      if (parse_stats(ct_ptr, probsfile, tabs_next_level, dim_of_cts - 1,
                      cts_each_dim + 1, tree, flatten_last_dim)) {
        return 1;
      }
      if (dim_of_cts == 2 || (dim_of_cts == 3 && flatten_last_dim)) {
148
149
150
151
        if (k == cts_each_dim[0] - 1)
          fprintf(probsfile, "}\n");
        else
          fprintf(probsfile, "},\n");
Yue Chen's avatar
Yue Chen committed
152
      } else {
153
154
155
156
        if (k == cts_each_dim[0] - 1)
          fprintf(probsfile, "%*c}\n", tabs * SPACES_PER_TAB, ' ');
        else
          fprintf(probsfile, "%*c},\n", tabs * SPACES_PER_TAB, ' ');
Yue Chen's avatar
Yue Chen committed
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
      }
    }
  }
  return 0;
}

// This function parses the stats of a syntax, either binary or multi-symbol,
// in different contexts, and writes the optimized probability table to
// probsfile.
//   counts: pointer of the first count element in counts array
//   probsfile: output file
//   dim_of_cts: number of dimensions of counts array
//   cts_each_dim: an array storing size of each dimension of counts array
//   tree: binary tree for a multi-symbol syntax, or NULL for a binary one
//   flatten_last_dim: for a binary syntax, if flatten_last_dim is 0, probs in
//                     different contexts will be written separately, e.g.,
//                     {{p1}, {p2}, ...};
//                     otherwise will be grouped together at the second last
//                     dimension, i.e.,
//                     {p1, p2, ...}.
//   prefix: declaration header for the entropy table
static void optimize_entropy_table(aom_count_type *counts,
                                   FILE *const probsfile, int dim_of_cts,
                                   int *cts_each_dim,
                                   const aom_tree_index *tree,
                                   int flatten_last_dim, char *prefix) {
  aom_count_type *ct_ptr = counts;

  assert(!flatten_last_dim || cts_each_dim[dim_of_cts - 1] == 2);

  fprintf(probsfile, "%s = {\n", prefix);
  if (parse_stats(&ct_ptr, probsfile, 1, dim_of_cts, cts_each_dim, tree,
                  flatten_last_dim)) {
    fprintf(probsfile, "Optimizer failed!\n");
  }
  fprintf(probsfile, "};\n\n");
  fprintf(logfile, "\n");
}

196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
static int counts_to_cdf(const aom_count_type *counts, aom_cdf_prob *cdf,
                         int modes) {
  int64_t *csum = aom_malloc(sizeof(*csum) * modes);

  if (csum == NULL) {
    fprintf(stderr, "Allocating csum array failed!\n");
    return 1;
  }
  csum[0] = counts[0];
  for (int i = 1; i < modes; ++i) csum[i] = counts[i] + csum[i - 1];

  int64_t sum = csum[modes - 1];
  int64_t round_shift = sum >> 1;
  for (int i = 0; i < modes; ++i) {
    if (sum <= 0)
      cdf[i] = CDF_PROB_TOP;
    else
      cdf[i] = (csum[i] * CDF_PROB_TOP + round_shift) / sum;
  }
215
  if (sum <= 0) cdf[0] = CDF_PROB_TOP - 1;
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
  return 0;
}

static int parse_counts_for_cdf_opt(aom_count_type **ct_ptr,
                                    FILE *const probsfile, int tabs,
                                    int dim_of_cts, int *cts_each_dim) {
  if (dim_of_cts < 1) {
    fprintf(stderr, "The dimension of a counts vector should be at least 1!\n");
    return 1;
  }
  if (dim_of_cts == 1) {
    const int total_modes = cts_each_dim[0];
    aom_count_type *counts1d = *ct_ptr;
    aom_cdf_prob *cdfs = aom_malloc(sizeof(*cdfs) * total_modes);

    if (cdfs == NULL) {
      fprintf(stderr, "Allocating cdf array failed!\n");
      return 1;
    }

    counts_to_cdf(counts1d, cdfs, total_modes);
    (*ct_ptr) += total_modes;

    if (tabs > 0) fprintf(probsfile, "%*c", tabs * SPACES_PER_TAB, ' ');
240
241
242
243
244
245
    fprintf(probsfile, "AOM_CDF%d( ", total_modes);
    for (int k = 0; k < total_modes - 1; ++k) {
      fprintf(probsfile, "%d", cdfs[k]);
      if (k < total_modes - 2) fprintf(probsfile, ",");
    }
    fprintf(probsfile, " )");
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
  } else {
    for (int k = 0; k < cts_each_dim[0]; ++k) {
      int tabs_next_level;

      if (dim_of_cts == 2)
        fprintf(probsfile, "%*c{", tabs * SPACES_PER_TAB, ' ');
      else
        fprintf(probsfile, "%*c{\n", tabs * SPACES_PER_TAB, ' ');
      tabs_next_level = dim_of_cts == 2 ? 0 : tabs + 1;

      if (parse_counts_for_cdf_opt(ct_ptr, probsfile, tabs_next_level,
                                   dim_of_cts - 1, cts_each_dim + 1)) {
        return 1;
      }

      if (dim_of_cts == 2) {
        if (k == cts_each_dim[0] - 1)
          fprintf(probsfile, "}\n");
        else
          fprintf(probsfile, "},\n");
      } else {
        if (k == cts_each_dim[0] - 1)
          fprintf(probsfile, "%*c}\n", tabs * SPACES_PER_TAB, ' ');
        else
          fprintf(probsfile, "%*c},\n", tabs * SPACES_PER_TAB, ' ');
      }
    }
  }

  return 0;
}

static void optimize_cdf_table(aom_count_type *counts, FILE *const probsfile,
                               int dim_of_cts, int *cts_each_dim,
                               char *prefix) {
  aom_count_type *ct_ptr = counts;

  fprintf(probsfile, "%s = {\n", prefix);
  if (parse_counts_for_cdf_opt(&ct_ptr, probsfile, 1, dim_of_cts,
                               cts_each_dim)) {
    fprintf(probsfile, "Optimizer failed!\n");
  }
  fprintf(probsfile, "};\n\n");
}

Yue Chen's avatar
Yue Chen committed
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
int main(int argc, const char **argv) {
  if (argc < 2) {
    fprintf(stderr, "Please specify the input stats file!\n");
    exit(EXIT_FAILURE);
  }

  FILE *const statsfile = fopen(argv[1], "rb");
  if (statsfile == NULL) {
    fprintf(stderr, "Failed to open input file!\n");
    exit(EXIT_FAILURE);
  }

  FRAME_COUNTS fc;
  fread(&fc, sizeof(FRAME_COUNTS), 1, statsfile);

  FILE *const probsfile = fopen("optimized_probs.c", "w");
  if (probsfile == NULL) {
    fprintf(stderr,
            "Failed to create output file for optimized entropy tables!\n");
    exit(EXIT_FAILURE);
  }

  logfile = fopen("aom_entropy_optimizer_parsed_counts.log", "w");
  if (logfile == NULL) {
    fprintf(stderr, "Failed to create log file for parsed counts!\n");
    exit(EXIT_FAILURE);
  }

  int cts_each_dim[10];

321
322
323
324
325
326
327
328
329
330
/* Intra mode (keyframe luma) */
#if CONFIG_KF_CTX
  cts_each_dim[0] = KF_MODE_CONTEXTS;
  cts_each_dim[1] = KF_MODE_CONTEXTS;
  cts_each_dim[2] = INTRA_MODES;
  optimize_cdf_table(&fc.kf_y_mode[0][0][0], probsfile, 3, cts_each_dim,
                     "const aom_cdf_prob\n"
                     "default_kf_y_mode_cdf[KF_MODE_CONTEXTS][KF_MODE_CONTEXTS]"
                     "[CDF_SIZE(INTRA_MODES)]");
#else
Yue Chen's avatar
Yue Chen committed
331
332
333
  cts_each_dim[0] = INTRA_MODES;
  cts_each_dim[1] = INTRA_MODES;
  cts_each_dim[2] = INTRA_MODES;
334
335
336
  optimize_cdf_table(
      &fc.kf_y_mode[0][0][0], probsfile, 3, cts_each_dim,
      "const aom_cdf_prob\n"
337
      "default_kf_y_mode_cdf[INTRA_MODES][INTRA_MODES][CDF_SIZE(INTRA_MODES)]");
338
#endif
Yue Chen's avatar
Yue Chen committed
339

Joe Young's avatar
Joe Young committed
340
341
342
343
344
345
346
  cts_each_dim[0] = DIRECTIONAL_MODES;
  cts_each_dim[1] = 2 * MAX_ANGLE_DELTA + 1;
  optimize_cdf_table(&fc.angle_delta[0][0], probsfile, 2, cts_each_dim,
                     "const aom_cdf_prob\n"
                     "default_angle_delta_cdf"
                     "[DIRECTIONAL_MODES][CDF_SIZE(2 * MAX_ANGLE_DELTA + 1)]");

Yue Chen's avatar
Yue Chen committed
347
348
349
  /* Intra mode (non-keyframe luma) */
  cts_each_dim[0] = BLOCK_SIZE_GROUPS;
  cts_each_dim[1] = INTRA_MODES;
350
351
352
353
  optimize_cdf_table(
      &fc.y_mode[0][0], probsfile, 2, cts_each_dim,
      "static const aom_cdf_prob\n"
      "default_if_y_mode_cdf[BLOCK_SIZE_GROUPS][CDF_SIZE(INTRA_MODES)]");
Yue Chen's avatar
Yue Chen committed
354
355
356

  /* Intra mode (chroma) */
  cts_each_dim[0] = INTRA_MODES;
Luc Trudeau's avatar
Luc Trudeau committed
357
358
359
360
361
  cts_each_dim[1] = UV_INTRA_MODES;
  optimize_cdf_table(
      &fc.uv_mode[0][0], probsfile, 2, cts_each_dim,
      "static const aom_cdf_prob\n"
      "default_uv_mode_cdf[INTRA_MODES][CDF_SIZE(UV_INTRA_MODES)]");
Yue Chen's avatar
Yue Chen committed
362
363
364
365
366

  /* Partition */
  cts_each_dim[0] = PARTITION_CONTEXTS;
#if CONFIG_EXT_PARTITION_TYPES
  cts_each_dim[1] = EXT_PARTITION_TYPES;
367
368
369
370
  optimize_cdf_table(&fc.partition[0][0], probsfile, 2, cts_each_dim,
                     "static const aom_cdf_prob\n"
                     "default_partition_cdf[PARTITION_CONTEXTS][CDF_SIZE(EXT_"
                     "PARTITION_TYPES)]");
Yue Chen's avatar
Yue Chen committed
371
372
#else
  cts_each_dim[1] = PARTITION_TYPES;
373
374
375
376
  optimize_cdf_table(
      &fc.partition[0][0], probsfile, 2, cts_each_dim,
      "static const aom_cdf_prob\n"
      "default_partition_cdf[PARTITION_CONTEXTS][CDF_SIZE(PARTITION_TYPES)]");
Yue Chen's avatar
Yue Chen committed
377
378
379
380
381
#endif

  /* Interpolation filter */
  cts_each_dim[0] = SWITCHABLE_FILTER_CONTEXTS;
  cts_each_dim[1] = SWITCHABLE_FILTERS;
382
383
384
385
  optimize_cdf_table(&fc.switchable_interp[0][0], probsfile, 2, cts_each_dim,
                     "static const aom_cdf_prob\n"
                     "default_switchable_interp_cdf[SWITCHABLE_FILTER_CONTEXTS]"
                     "[CDF_SIZE(SWITCHABLE_FILTERS)]");
Yue Chen's avatar
Yue Chen committed
386
387
388
389
390

  /* Motion vector referencing */
  cts_each_dim[0] = NEWMV_MODE_CONTEXTS;
  cts_each_dim[1] = 2;
  optimize_entropy_table(
391
      &fc.newmv_mode[0][0], probsfile, 2, cts_each_dim, NULL, 1,
Yue Chen's avatar
Yue Chen committed
392
      "static const aom_prob default_newmv_prob[NEWMV_MODE_CONTEXTS]");
393
394
395
  optimize_cdf_table(&fc.newmv_mode[0][0], probsfile, 2, cts_each_dim,
                     "static const aom_cdf_prob "
                     "default_newmv_cdf[NEWMV_MODE_CONTEXTS][CDF_SIZE(2)]");
Yue Chen's avatar
Yue Chen committed
396

Sarah Parker's avatar
Sarah Parker committed
397
  cts_each_dim[0] = GLOBALMV_MODE_CONTEXTS;
Yue Chen's avatar
Yue Chen committed
398
399
  cts_each_dim[1] = 2;
  optimize_entropy_table(
400
      &fc.zeromv_mode[0][0], probsfile, 2, cts_each_dim, NULL, 1,
Sarah Parker's avatar
Sarah Parker committed
401
      "static const aom_prob default_zeromv_prob[GLOBALMV_MODE_CONTEXTS]");
402
403
  optimize_cdf_table(&fc.zeromv_mode[0][0], probsfile, 2, cts_each_dim,
                     "static const aom_cdf_prob "
Sarah Parker's avatar
Sarah Parker committed
404
                     "default_zeromv_cdf[GLOBALMV_MODE_CONTEXTS][CDF_SIZE(2)]");
Yue Chen's avatar
Yue Chen committed
405
406
407
408

  cts_each_dim[0] = REFMV_MODE_CONTEXTS;
  cts_each_dim[1] = 2;
  optimize_entropy_table(
409
      &fc.refmv_mode[0][0], probsfile, 2, cts_each_dim, NULL, 1,
Yue Chen's avatar
Yue Chen committed
410
      "static const aom_prob default_refmv_prob[REFMV_MODE_CONTEXTS]");
411
412
413
  optimize_cdf_table(&fc.refmv_mode[0][0], probsfile, 2, cts_each_dim,
                     "static const aom_cdf_prob "
                     "default_refmv_cdf[REFMV_MODE_CONTEXTS][CDF_SIZE(2)]");
Yue Chen's avatar
Yue Chen committed
414
415
416
417

  cts_each_dim[0] = DRL_MODE_CONTEXTS;
  cts_each_dim[1] = 2;
  optimize_entropy_table(
418
      &fc.drl_mode[0][0], probsfile, 2, cts_each_dim, NULL, 1,
Yue Chen's avatar
Yue Chen committed
419
      "static const aom_prob default_drl_prob[DRL_MODE_CONTEXTS]");
420
421
422
  optimize_cdf_table(&fc.drl_mode[0][0], probsfile, 2, cts_each_dim,
                     "static const aom_cdf_prob "
                     "default_drl_cdf[DRL_MODE_CONTEXTS][CDF_SIZE(2)]");
Yue Chen's avatar
Yue Chen committed
423

424
  /* ext_inter experiment */
Yue Chen's avatar
Yue Chen committed
425
426
427
  /* New compound mode */
  cts_each_dim[0] = INTER_MODE_CONTEXTS;
  cts_each_dim[1] = INTER_COMPOUND_MODES;
428
429
430
431
  optimize_cdf_table(&fc.inter_compound_mode[0][0], probsfile, 2, cts_each_dim,
                     "static const aom_cdf_prob\n"
                     "default_inter_compound_mode_cdf[INTER_MODE_CONTEXTS][CDF_"
                     "SIZE(INTER_COMPOUND_MODES)]");
Yue Chen's avatar
Yue Chen committed
432

Yue Chen's avatar
Yue Chen committed
433
434
435
  /* Interintra */
  cts_each_dim[0] = BLOCK_SIZE_GROUPS;
  cts_each_dim[1] = 2;
436
437
438
  optimize_cdf_table(&fc.interintra[0][0], probsfile, 2, cts_each_dim,
                     "static const aom_cdf_prob "
                     "default_interintra_cdf[BLOCK_SIZE_GROUPS][CDF_SIZE(2)]");
Yue Chen's avatar
Yue Chen committed
439
440
441

  cts_each_dim[0] = BLOCK_SIZE_GROUPS;
  cts_each_dim[1] = INTERINTRA_MODES;
442
443
444
445
  optimize_cdf_table(&fc.interintra_mode[0][0], probsfile, 2, cts_each_dim,
                     "static const aom_cdf_prob\n"
                     "default_interintra_mode_cdf[BLOCK_SIZE_GROUPS][CDF_SIZE("
                     "INTERINTRA_MODES)]");
Yue Chen's avatar
Yue Chen committed
446

447
  cts_each_dim[0] = BLOCK_SIZES_ALL;
Yue Chen's avatar
Yue Chen committed
448
  cts_each_dim[1] = 2;
449
450
451
452
  optimize_cdf_table(
      &fc.wedge_interintra[0][0], probsfile, 2, cts_each_dim,
      "static const aom_cdf_prob\n"
      "default_wedge_interintra_cdf[BLOCK_SIZES_ALL][CDF_SIZE(2)]");
Yue Chen's avatar
Yue Chen committed
453

Yue Chen's avatar
Yue Chen committed
454
  /* Compound type */
455
  cts_each_dim[0] = BLOCK_SIZES_ALL;
Yue Chen's avatar
Yue Chen committed
456
  cts_each_dim[1] = COMPOUND_TYPES;
457
458
459
460
  optimize_cdf_table(
      &fc.compound_interinter[0][0], probsfile, 2, cts_each_dim,
      "static const aom_cdf_prob\n"
      "default_compound_type_cdf[BLOCK_SIZES_ALL][CDF_SIZE(COMPOUND_TYPES)]");
Yue Chen's avatar
Yue Chen committed
461

462
  /* motion_var and warped_motion experiments */
463
  cts_each_dim[0] = BLOCK_SIZES_ALL;
Yue Chen's avatar
Yue Chen committed
464
465
  cts_each_dim[1] = MOTION_MODES;
  optimize_entropy_table(
466
      &fc.motion_mode[0][0], probsfile, 2, cts_each_dim, av1_motion_mode_tree,
Yue Chen's avatar
Yue Chen committed
467
468
469
      0,
      "static const aom_prob default_motion_mode_prob[BLOCK_SIZES]"
      "[MOTION_MODES - 1]");
470
471
472
473
474
  optimize_cdf_table(
      &fc.motion_mode[0][0], probsfile, 2, cts_each_dim,
      "static const aom_cdf_prob\n"
      "default_motion_mode_cdf[BLOCK_SIZES_ALL][CDF_SIZE(MOTION_MODES)]");
  cts_each_dim[0] = BLOCK_SIZES_ALL;
Yue Chen's avatar
Yue Chen committed
475
  cts_each_dim[1] = 2;
476
477
478
  optimize_cdf_table(&fc.obmc[0][0], probsfile, 2, cts_each_dim,
                     "static const aom_cdf_prob "
                     "default_obmc_cdf[BLOCK_SIZES_ALL][CDF_SIZE(2)]");
Yue Chen's avatar
Yue Chen committed
479
480
481
482

  /* Intra/inter flag */
  cts_each_dim[0] = INTRA_INTER_CONTEXTS;
  cts_each_dim[1] = 2;
483
  optimize_entropy_table(&fc.intra_inter[0][0], probsfile, 2, cts_each_dim,
Yue Chen's avatar
Yue Chen committed
484
485
486
                         NULL, 1,
                         "static const aom_prob default_intra_inter_p"
                         "[INTRA_INTER_CONTEXTS]");
487
488
489
490
  optimize_cdf_table(
      &fc.intra_inter[0][0], probsfile, 2, cts_each_dim,
      "static const aom_cdf_prob\n"
      "default_intra_inter_cdf[INTRA_INTER_CONTEXTS][CDF_SIZE(2)]");
Yue Chen's avatar
Yue Chen committed
491
492
493
494

  /* Single/comp ref flag */
  cts_each_dim[0] = COMP_INTER_CONTEXTS;
  cts_each_dim[1] = 2;
495
496
  optimize_entropy_table(&fc.comp_inter[0][0], probsfile, 2, cts_each_dim, NULL,
                         1,
Yue Chen's avatar
Yue Chen committed
497
498
                         "static const aom_prob default_comp_inter_p"
                         "[COMP_INTER_CONTEXTS]");
499
500
501
502
  optimize_cdf_table(
      &fc.comp_inter[0][0], probsfile, 2, cts_each_dim,
      "static const aom_cdf_prob\n"
      "default_comp_inter_cdf[COMP_INTER_CONTEXTS][CDF_SIZE(2)]");
Yue Chen's avatar
Yue Chen committed
503
504
505
506
507
508

/* ext_comp_refs experiment */
#if CONFIG_EXT_COMP_REFS
  cts_each_dim[0] = COMP_REF_TYPE_CONTEXTS;
  cts_each_dim[1] = 2;
  optimize_entropy_table(
509
      &fc.comp_ref_type[0][0], probsfile, 2, cts_each_dim, NULL, 1,
Yue Chen's avatar
Yue Chen committed
510
      "static const aom_prob default_comp_ref_type_p[COMP_REF_TYPE_CONTEXTS]");
511
512
513
514
  optimize_cdf_table(
      &fc.comp_ref_type[0][0], probsfile, 2, cts_each_dim,
      "static const aom_cdf_prob\n"
      "default_comp_ref_type_cdf[COMP_REF_TYPE_CONTEXTS][CDF_SIZE(2)]");
Yue Chen's avatar
Yue Chen committed
515
516
517
518
519

  cts_each_dim[0] = UNI_COMP_REF_CONTEXTS;
  cts_each_dim[1] = UNIDIR_COMP_REFS - 1;
  cts_each_dim[2] = 2;
  optimize_entropy_table(
520
      &fc.uni_comp_ref[0][0][0], probsfile, 3, cts_each_dim, NULL, 1,
Yue Chen's avatar
Yue Chen committed
521
522
      "static const aom_prob\n"
      "default_uni_comp_ref_p[UNI_COMP_REF_CONTEXTS][UNIDIR_COMP_REFS - 1]");
523
524
525
526
  optimize_cdf_table(&fc.uni_comp_ref[0][0][0], probsfile, 3, cts_each_dim,
                     "static const aom_cdf_prob\n"
                     "default_uni_comp_ref_cdf[UNI_COMP_REF_CONTEXTS][UNIDIR_"
                     "COMP_REFS - 1][CDF_SIZE(2)]");
Yue Chen's avatar
Yue Chen committed
527
528
529
530
531
532
533
#endif

  /* Reference frame (single ref) */
  cts_each_dim[0] = REF_CONTEXTS;
  cts_each_dim[1] = SINGLE_REFS - 1;
  cts_each_dim[2] = 2;
  optimize_entropy_table(
534
      &fc.single_ref[0][0][0], probsfile, 3, cts_each_dim, NULL, 1,
Yue Chen's avatar
Yue Chen committed
535
536
      "static const aom_prob default_single_ref_p[REF_CONTEXTS]"
      "[SINGLE_REFS - 1]");
537
538
539
540
  optimize_cdf_table(
      &fc.single_ref[0][0][0], probsfile, 3, cts_each_dim,
      "static const aom_cdf_prob\n"
      "default_single_ref_cdf[REF_CONTEXTS][SINGLE_REFS - 1][CDF_SIZE(2)]");
Yue Chen's avatar
Yue Chen committed
541
542
543
544
545
546

  /* ext_refs experiment */
  cts_each_dim[0] = REF_CONTEXTS;
  cts_each_dim[1] = FWD_REFS - 1;
  cts_each_dim[2] = 2;
  optimize_entropy_table(
547
      &fc.comp_ref[0][0][0], probsfile, 3, cts_each_dim, NULL, 1,
Yue Chen's avatar
Yue Chen committed
548
      "static const aom_prob default_comp_ref_p[REF_CONTEXTS][FWD_REFS - 1]");
549
550
551
552
  optimize_cdf_table(
      &fc.comp_ref[0][0][0], probsfile, 3, cts_each_dim,
      "static const aom_cdf_prob\n"
      "default_comp_ref_cdf[REF_CONTEXTS][FWD_REFS - 1][CDF_SIZE(2)]");
Yue Chen's avatar
Yue Chen committed
553
554
555
556

  cts_each_dim[0] = REF_CONTEXTS;
  cts_each_dim[1] = BWD_REFS - 1;
  cts_each_dim[2] = 2;
557
  optimize_entropy_table(&fc.comp_bwdref[0][0][0], probsfile, 3, cts_each_dim,
Yue Chen's avatar
Yue Chen committed
558
559
560
                         NULL, 1,
                         "static const aom_prob "
                         "default_comp_bwdref_p[REF_CONTEXTS][BWD_REFS - 1]");
561
562
563
564
  optimize_cdf_table(
      &fc.comp_bwdref[0][0][0], probsfile, 3, cts_each_dim,
      "static const aom_cdf_prob\n"
      "default_comp_bwdref_cdf[REF_CONTEXTS][BWD_REFS - 1][CDF_SIZE(2)]");
Yue Chen's avatar
Yue Chen committed
565

566
  /* Transform size */
Yue Chen's avatar
Yue Chen committed
567
568
  cts_each_dim[0] = TXFM_PARTITION_CONTEXTS;
  cts_each_dim[1] = 2;
569
570
571
572
  optimize_cdf_table(
      &fc.txfm_partition[0][0], probsfile, 2, cts_each_dim,
      "static const aom_cdf_prob\n"
      "default_txfm_partition_cdf[TXFM_PARTITION_CONTEXTS][CDF_SIZE(2)]");
Yue Chen's avatar
Yue Chen committed
573
574
575
576
577

  /* Skip flag */
  cts_each_dim[0] = SKIP_CONTEXTS;
  cts_each_dim[1] = 2;
  optimize_entropy_table(
578
      &fc.skip[0][0], probsfile, 2, cts_each_dim, NULL, 1,
Yue Chen's avatar
Yue Chen committed
579
      "static const aom_prob default_skip_probs[SKIP_CONTEXTS]");
580
581
582
  optimize_cdf_table(&fc.skip[0][0], probsfile, 2, cts_each_dim,
                     "static const aom_cdf_prob "
                     "default_skip_cdfs[SKIP_CONTEXTS][CDF_SIZE(2)]");
Yue Chen's avatar
Yue Chen committed
583
584
585
586

/* intrabc experiment */
#if CONFIG_INTRABC
  cts_each_dim[0] = 2;
587
  optimize_entropy_table(&fc.intrabc[0], probsfile, 1, cts_each_dim, NULL, 1,
Yue Chen's avatar
Yue Chen committed
588
                         "INTRABC_PROB_DEFAULT");
589
590
591
  optimize_cdf_table(
      &fc.intrabc[0], probsfile, 1, cts_each_dim,
      "static const aom_cdf_prob default_intrabc_cdf[CDF_SIZE(2)]");
Yue Chen's avatar
Yue Chen committed
592
593
594
595
596
597
598
599
600
601
#endif

/* Transform type */
// TODO(yuec): different trees are used depending on selected ext tx set

/* supertx experiment */

/* filter_intra experiment */
#if CONFIG_FILTER_INTRA
  cts_each_dim[0] = PLANE_TYPES;
602
603
604
605
606
  cts_each_dim[1] = FILTER_INTRA_MODES;
  optimize_cdf_table(
      &fc.filter_intra_mode[0][0], probsfile, 2, cts_each_dim,
      "static const aom_cdf_prob "
      "default_filter_intra_mode_cdf[2][CDF_SIZE(FILTER_INTRA_MODES)]");
607
608
609
610
611
612

  cts_each_dim[0] = TX_SIZES_ALL;
  cts_each_dim[1] = 2;
  optimize_cdf_table(&fc.filter_intra_tx[0][0], probsfile, 2, cts_each_dim,
                     "static const aom_cdf_prob "
                     "default_filter_intra_cdfs[TX_SIZES_ALL][CDF_SIZE(2)]");
613
614
615
616
617
618
619
620
621

  cts_each_dim[0] = KF_MODE_CONTEXTS;
  cts_each_dim[1] = KF_MODE_CONTEXTS;
  cts_each_dim[2] = FILTER_INTRA_MODES;
  optimize_cdf_table(&fc.filter_intra_mode_ctx[0][0][0], probsfile, 3,
                     cts_each_dim,
                     "static const aom_cdf_prob "
                     "default_filter_intra_mode_cdf[KF_MODE_CONTEXTS][KF_MODE_"
                     "CONTEXTS][CDF_SIZE(FILTER_INTRA_MODES)]");
Yue Chen's avatar
Yue Chen committed
622
623
#endif

624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
#if CONFIG_LV_MAP
  cts_each_dim[0] = TX_SIZES;
  cts_each_dim[1] = PLANE_TYPES;
  cts_each_dim[2] = NUM_BASE_LEVELS;
  cts_each_dim[3] = COEFF_BASE_CONTEXTS;
  cts_each_dim[4] = 2;
  optimize_entropy_table(&fc.coeff_base[0][0][0][0][0], probsfile, 5,
                         cts_each_dim, NULL, 1,
                         "static const aom_prob "
                         "default_coeff_base[TX_SIZES][PLANE_TYPES][NUM_BASE_"
                         "LEVELS][COEFF_BASE_CONTEXTS]");
  optimize_cdf_table(&fc.coeff_base[0][0][0][0][0], probsfile, 5, cts_each_dim,
                     "static const aom_cdf_prob "
                     "default_coeff_base_cdf[TX_SIZES][PLANE_TYPES][NUM_BASE_"
                     "LEVELS][COEFF_BASE_CONTEXTS][CDF_SIZE(2)]");

Jingning Han's avatar
Jingning Han committed
640
641
642
643
644
645
646
647
648
649
650
651
  cts_each_dim[0] = TX_SIZES;
  cts_each_dim[1] = TXB_SKIP_CONTEXTS;
  cts_each_dim[2] = 2;
  optimize_entropy_table(
      &fc.txb_skip[0][0][0], probsfile, 3, cts_each_dim, NULL, 1,
      "static const aom_prob "
      "default_txk_skip[TX_SIZES][PLANE_TYPES][SIG_COEF_CONTEXTS]");
  optimize_cdf_table(&fc.txb_skip[0][0][0], probsfile, 3, cts_each_dim,
                     "static const aom_cdf_prob "
                     "default_nz_map_cdf[TX_SIZES][PLANE_TYPES][SIG_COEF_"
                     "CONTEXTS][CDF_SIZE(2)]");

652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
  cts_each_dim[0] = TX_SIZES;
  cts_each_dim[1] = PLANE_TYPES;
  cts_each_dim[2] = SIG_COEF_CONTEXTS;
  cts_each_dim[3] = 2;
  optimize_entropy_table(
      &fc.nz_map[0][0][0][0], probsfile, 4, cts_each_dim, NULL, 1,
      "static const aom_prob "
      "default_nz_map[TX_SIZES][PLANE_TYPES][SIG_COEF_CONTEXTS]");
  optimize_cdf_table(&fc.nz_map[0][0][0][0], probsfile, 4, cts_each_dim,
                     "static const aom_cdf_prob "
                     "default_nz_map_cdf[TX_SIZES][PLANE_TYPES][SIG_COEF_"
                     "CONTEXTS][CDF_SIZE(2)]");

  cts_each_dim[0] = TX_SIZES;
  cts_each_dim[1] = PLANE_TYPES;
  cts_each_dim[2] = EOB_COEF_CONTEXTS;
  cts_each_dim[3] = 2;
  optimize_entropy_table(
      &fc.eob_flag[0][0][0][0], probsfile, 4, cts_each_dim, NULL, 1,
      "static const aom_prob "
      "default_eob_flag[TX_SIZES][PLANE_TYPES][EOB_COEF_CONTEXTS]");
  optimize_cdf_table(&fc.eob_flag[0][0][0][0], probsfile, 4, cts_each_dim,
                     "static const aom_cdf_prob "
                     "default_eob_flag_cdf[TX_SIZES][PLANE_TYPES][EOB_COEF_"
                     "CONTEXTS][CDF_SIZE(2)]");

678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
  cts_each_dim[0] = TX_SIZES;
  cts_each_dim[1] = PLANE_TYPES;
  cts_each_dim[2] = EOB_COEF_CONTEXTS;
  cts_each_dim[3] = 2;
  optimize_entropy_table(
      &fc.eob_extra[0][0][0][0], probsfile, 4, cts_each_dim, NULL, 1,
      "static const aom_prob "
      "default_eob_extra[TX_SIZES][PLANE_TYPES][EOB_COEF_CONTEXTS]");

#if CONFIG_LV_MAP_MULTI
  cts_each_dim[0] = TX_SIZES;
  cts_each_dim[1] = PLANE_TYPES;
  cts_each_dim[2] = BR_CDF_SIZE - 1;
  cts_each_dim[3] = LEVEL_CONTEXTS;
  cts_each_dim[4] = 2;
  optimize_entropy_table(&fc.coeff_lps[0][0][0][0][0], probsfile, 5,
                         cts_each_dim, NULL, 1,
                         "static const aom_prob "
                         "default_coeff_lps[TX_SIZES][PLANE_TYPES][BR_CDF_SIZE-"
                         "1][LEVEL_CONTEXTS]");
#else
699
700
701
702
703
704
705
706
707
708
709
710
  cts_each_dim[0] = TX_SIZES;
  cts_each_dim[1] = PLANE_TYPES;
  cts_each_dim[2] = LEVEL_CONTEXTS;
  cts_each_dim[3] = 2;
  optimize_entropy_table(
      &fc.coeff_lps[0][0][0][0], probsfile, 4, cts_each_dim, NULL, 1,
      "static const aom_prob "
      "default_coeff_lps[TX_SIZES][PLANE_TYPES][LEVEL_CONTEXTS]");
  optimize_cdf_table(&fc.coeff_lps[0][0][0][0], probsfile, 4, cts_each_dim,
                     "static const aom_cdf_prob "
                     "default_coeff_lps_cdf[TX_SIZES][PLANE_TYPES][LEVEL_"
                     "CONTEXTS][CDF_SIZE(2)]");
711

712
713
714
715
716
717
718
719
720
721
722
723
724
725
  cts_each_dim[0] = TX_SIZES;
  cts_each_dim[1] = PLANE_TYPES;
  cts_each_dim[2] = BASE_RANGE_SETS;
  cts_each_dim[3] = LEVEL_CONTEXTS;
  cts_each_dim[4] = 2;
  optimize_entropy_table(&fc.coeff_br[0][0][0][0][0], probsfile, 5,
                         cts_each_dim, NULL, 1,
                         "static const aom_prob "
                         "default_coeff_br[TX_SIZES][PLANE_TYPES][BASE_RANGE_"
                         "SETS][LEVEL_CONTEXTS]");
  optimize_cdf_table(&fc.coeff_br[0][0][0][0][0], probsfile, 5, cts_each_dim,
                     "static const aom_cdf_prob "
                     "default_coeff_br_cdf[TX_SIZES][PLANE_TYPES][BASE_RANGE_"
                     "SETS][LEVEL_CONTEXTS][CDF_SIZE(2)]");
726
#endif
727

728
#endif  // CONFIG_LV_MAP
729

730
/* lgt_from_pred experiment */
Cheng Chen's avatar
Cheng Chen committed
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
#if CONFIG_LPF_SB
  cts_each_dim[0] = LPF_REUSE_CONTEXT;
  cts_each_dim[1] = 2;
  optimize_cdf_table(&fc.lpf_reuse[0][0], probsfile, 2, cts_each_dim,
                     "static const aom_cdf_prob "
                     "default_lpf_reuse_cdf[LPF_REUSE_CONTEXT][CDF_SIZE(2)]");

  cts_each_dim[0] = LPF_DELTA_CONTEXT;
  cts_each_dim[1] = DELTA_RANGE;
  optimize_cdf_table(&fc.lpf_delta[0][0], probsfile, 2, cts_each_dim,
                     "static const aom_cdf_prob "
                     "default_lpf_delta_cdf[LPF_DELTA_CONTEXT][CDF_SIZE(DELTA_"
                     "RANGE)]");

  cts_each_dim[0] = LPF_REUSE_CONTEXT;
  cts_each_dim[1] = LPF_SIGN_CONTEXT;
  cts_each_dim[2] = 2;
  optimize_cdf_table(&fc.lpf_delta[0][0], probsfile, 3, cts_each_dim,
                     "static const aom_cdf_prob "
                     "default_lpf_sign_cdf[LPF_REUSE_CONTEXT][LPF_SIGN_CONTEXT]"
                     "[CDF_SIZE(2)]");
#endif
753

754
755
756
757
758
759
760
761
762
763
764
765
#if CONFIG_EXT_SKIP
  /* Skip mode flag */
  cts_each_dim[0] = SKIP_MODE_CONTEXTS;
  cts_each_dim[1] = 2;
  optimize_entropy_table(
      &fc.skip_mode[0][0], probsfile, 2, cts_each_dim, NULL, 1,
      "static const aom_prob default_skip_mode_probs[SKIP_MODE_CONTEXTS]");
  optimize_cdf_table(&fc.skip_mode[0][0], probsfile, 2, cts_each_dim,
                     "static const aom_cdf_prob "
                     "default_skip_mode_cdfs[SKIP_MODE_CONTEXTS][CDF_SIZE(2)]");
#endif  // CONFIG_EXT_SKIP

Yue Chen's avatar
Yue Chen committed
766
767
768
769
770
771
  fclose(statsfile);
  fclose(logfile);
  fclose(probsfile);

  return 0;
}