xref: /aosp_15_r20/external/libaom/tools/aom_entropy_optimizer.c (revision 77c1e3ccc04c968bd2bc212e87364f250e820521)
1 /*
2  * Copyright (c) 2017, Alliance for Open Media. All rights reserved.
3  *
4  * This source code is subject to the terms of the BSD 2 Clause License and
5  * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
6  * was not distributed with this source code in the LICENSE file, you can
7  * obtain it at www.aomedia.org/license/software. If the Alliance for Open
8  * Media Patent License 1.0 was not distributed with this source code in the
9  * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
10  */
11 
12 // This tool is a gadget for offline probability training.
13 // A binary executable aom_entropy_optimizer will be generated in tools/. It
14 // parses a binary file consisting of counts written in the format of
15 // FRAME_COUNTS in entropymode.h, and computes optimized probability tables
16 // and CDF tables, which will be written to a new c file optimized_probs.c
17 // according to format in the codebase.
18 //
19 // Command line: ./aom_entropy_optimizer [directory of the count file]
20 //
21 // The input file can either be generated by encoding a single clip by
22 // turning on entropy_stats experiment, or be collected at a larger scale at
23 // which a python script which will be provided soon can be used to aggregate
24 // multiple stats output.
25 
26 #include <assert.h>
27 #include <stdio.h>
28 
29 #include "config/aom_config.h"
30 
31 #include "av1/encoder/encoder.h"
32 
33 #define SPACES_PER_TAB 2
34 #define CDF_MAX_SIZE 16
35 
36 typedef unsigned int aom_count_type;
37 // A log file recording parsed counts
38 static FILE *logfile;  // TODO(yuec): make it a command line option
39 
counts_to_cdf(const aom_count_type * counts,aom_cdf_prob * cdf,int modes)40 static void counts_to_cdf(const aom_count_type *counts, aom_cdf_prob *cdf,
41                           int modes) {
42   int64_t csum[CDF_MAX_SIZE];
43   assert(modes <= CDF_MAX_SIZE);
44 
45   csum[0] = counts[0] + 1;
46   for (int i = 1; i < modes; ++i) csum[i] = counts[i] + 1 + csum[i - 1];
47 
48   for (int i = 0; i < modes; ++i) fprintf(logfile, "%d ", counts[i]);
49   fprintf(logfile, "\n");
50 
51   int64_t sum = csum[modes - 1];
52   const int64_t round_shift = sum >> 1;
53   for (int i = 0; i < modes; ++i) {
54     cdf[i] = (csum[i] * CDF_PROB_TOP + round_shift) / sum;
55     cdf[i] = AOMMIN(cdf[i], CDF_PROB_TOP - (modes - 1 + i) * 4);
56     cdf[i] = (i == 0) ? AOMMAX(cdf[i], 4) : AOMMAX(cdf[i], cdf[i - 1] + 4);
57   }
58 }
59 
parse_counts_for_cdf_opt(aom_count_type ** ct_ptr,FILE * const probsfile,int tabs,int dim_of_cts,int * cts_each_dim)60 static int parse_counts_for_cdf_opt(aom_count_type **ct_ptr,
61                                     FILE *const probsfile, int tabs,
62                                     int dim_of_cts, int *cts_each_dim) {
63   if (dim_of_cts < 1) {
64     fprintf(stderr, "The dimension of a counts vector should be at least 1!\n");
65     return 1;
66   }
67   const int total_modes = cts_each_dim[0];
68   if (dim_of_cts == 1) {
69     assert(total_modes <= CDF_MAX_SIZE);
70     aom_cdf_prob cdfs[CDF_MAX_SIZE];
71     aom_count_type *counts1d = *ct_ptr;
72 
73     counts_to_cdf(counts1d, cdfs, total_modes);
74     (*ct_ptr) += total_modes;
75 
76     if (tabs > 0) fprintf(probsfile, "%*c", tabs * SPACES_PER_TAB, ' ');
77     fprintf(probsfile, "AOM_CDF%d(", total_modes);
78     for (int k = 0; k < total_modes - 1; ++k) {
79       fprintf(probsfile, "%d", cdfs[k]);
80       if (k < total_modes - 2) fprintf(probsfile, ", ");
81     }
82     fprintf(probsfile, ")");
83   } else {
84     for (int k = 0; k < total_modes; ++k) {
85       int tabs_next_level;
86 
87       if (dim_of_cts == 2)
88         fprintf(probsfile, "%*c{ ", tabs * SPACES_PER_TAB, ' ');
89       else
90         fprintf(probsfile, "%*c{\n", tabs * SPACES_PER_TAB, ' ');
91       tabs_next_level = dim_of_cts == 2 ? 0 : tabs + 1;
92 
93       if (parse_counts_for_cdf_opt(ct_ptr, probsfile, tabs_next_level,
94                                    dim_of_cts - 1, cts_each_dim + 1)) {
95         return 1;
96       }
97 
98       if (dim_of_cts == 2) {
99         if (k == total_modes - 1)
100           fprintf(probsfile, " }\n");
101         else
102           fprintf(probsfile, " },\n");
103       } else {
104         if (k == total_modes - 1)
105           fprintf(probsfile, "%*c}\n", tabs * SPACES_PER_TAB, ' ');
106         else
107           fprintf(probsfile, "%*c},\n", tabs * SPACES_PER_TAB, ' ');
108       }
109     }
110   }
111   return 0;
112 }
113 
optimize_cdf_table(aom_count_type * counts,FILE * const probsfile,int dim_of_cts,int * cts_each_dim,char * prefix)114 static void optimize_cdf_table(aom_count_type *counts, FILE *const probsfile,
115                                int dim_of_cts, int *cts_each_dim,
116                                char *prefix) {
117   aom_count_type *ct_ptr = counts;
118 
119   fprintf(probsfile, "%s = {\n", prefix);
120   fprintf(logfile, "%s\n", prefix);
121   if (parse_counts_for_cdf_opt(&ct_ptr, probsfile, 1, dim_of_cts,
122                                cts_each_dim)) {
123     fprintf(probsfile, "Optimizer failed!\n");
124   }
125   fprintf(probsfile, "};\n\n");
126   fprintf(logfile, "============================\n");
127 }
128 
optimize_uv_mode(aom_count_type * counts,FILE * const probsfile,int dim_of_cts,int * cts_each_dim,char * prefix)129 static void optimize_uv_mode(aom_count_type *counts, FILE *const probsfile,
130                              int dim_of_cts, int *cts_each_dim, char *prefix) {
131   aom_count_type *ct_ptr = counts;
132 
133   fprintf(probsfile, "%s = {\n", prefix);
134   fprintf(probsfile, "%*c{\n", SPACES_PER_TAB, ' ');
135   fprintf(logfile, "%s\n", prefix);
136   cts_each_dim[2] = UV_INTRA_MODES - 1;
137   for (int k = 0; k < cts_each_dim[1]; ++k) {
138     fprintf(probsfile, "%*c{ ", 2 * SPACES_PER_TAB, ' ');
139     parse_counts_for_cdf_opt(&ct_ptr, probsfile, 0, dim_of_cts - 2,
140                              cts_each_dim + 2);
141     if (k + 1 == cts_each_dim[1]) {
142       fprintf(probsfile, " }\n");
143     } else {
144       fprintf(probsfile, " },\n");
145     }
146     ++ct_ptr;
147   }
148   fprintf(probsfile, "%*c},\n", SPACES_PER_TAB, ' ');
149   fprintf(probsfile, "%*c{\n", SPACES_PER_TAB, ' ');
150   cts_each_dim[2] = UV_INTRA_MODES;
151   parse_counts_for_cdf_opt(&ct_ptr, probsfile, 2, dim_of_cts - 1,
152                            cts_each_dim + 1);
153   fprintf(probsfile, "%*c}\n", SPACES_PER_TAB, ' ');
154   fprintf(probsfile, "};\n\n");
155   fprintf(logfile, "============================\n");
156 }
157 
optimize_cdf_table_var_modes_2d(aom_count_type * counts,FILE * const probsfile,int dim_of_cts,int * cts_each_dim,int * modes_each_ctx,char * prefix)158 static void optimize_cdf_table_var_modes_2d(aom_count_type *counts,
159                                             FILE *const probsfile,
160                                             int dim_of_cts, int *cts_each_dim,
161                                             int *modes_each_ctx, char *prefix) {
162   aom_count_type *ct_ptr = counts;
163 
164   assert(dim_of_cts == 2);
165   (void)dim_of_cts;
166 
167   fprintf(probsfile, "%s = {\n", prefix);
168   fprintf(logfile, "%s\n", prefix);
169 
170   for (int d0_idx = 0; d0_idx < cts_each_dim[0]; ++d0_idx) {
171     int num_of_modes = modes_each_ctx[d0_idx];
172 
173     if (num_of_modes > 0) {
174       fprintf(probsfile, "%*c{ ", SPACES_PER_TAB, ' ');
175       parse_counts_for_cdf_opt(&ct_ptr, probsfile, 0, 1, &num_of_modes);
176       ct_ptr += cts_each_dim[1] - num_of_modes;
177       fprintf(probsfile, " },\n");
178     } else {
179       fprintf(probsfile, "%*c{ 0 },\n", SPACES_PER_TAB, ' ');
180       fprintf(logfile, "dummy cdf, no need to optimize\n");
181       ct_ptr += cts_each_dim[1];
182     }
183   }
184   fprintf(probsfile, "};\n\n");
185   fprintf(logfile, "============================\n");
186 }
187 
optimize_cdf_table_var_modes_3d(aom_count_type * counts,FILE * const probsfile,int dim_of_cts,int * cts_each_dim,int * modes_each_ctx,char * prefix)188 static void optimize_cdf_table_var_modes_3d(aom_count_type *counts,
189                                             FILE *const probsfile,
190                                             int dim_of_cts, int *cts_each_dim,
191                                             int *modes_each_ctx, char *prefix) {
192   aom_count_type *ct_ptr = counts;
193 
194   assert(dim_of_cts == 3);
195   (void)dim_of_cts;
196 
197   fprintf(probsfile, "%s = {\n", prefix);
198   fprintf(logfile, "%s\n", prefix);
199 
200   for (int d0_idx = 0; d0_idx < cts_each_dim[0]; ++d0_idx) {
201     fprintf(probsfile, "%*c{\n", SPACES_PER_TAB, ' ');
202     for (int d1_idx = 0; d1_idx < cts_each_dim[1]; ++d1_idx) {
203       int num_of_modes = modes_each_ctx[d0_idx];
204 
205       if (num_of_modes > 0) {
206         fprintf(probsfile, "%*c{ ", 2 * SPACES_PER_TAB, ' ');
207         parse_counts_for_cdf_opt(&ct_ptr, probsfile, 0, 1, &num_of_modes);
208         ct_ptr += cts_each_dim[2] - num_of_modes;
209         fprintf(probsfile, " },\n");
210       } else {
211         fprintf(probsfile, "%*c{ 0 },\n", 2 * SPACES_PER_TAB, ' ');
212         fprintf(logfile, "dummy cdf, no need to optimize\n");
213         ct_ptr += cts_each_dim[2];
214       }
215     }
216     fprintf(probsfile, "%*c},\n", SPACES_PER_TAB, ' ');
217   }
218   fprintf(probsfile, "};\n\n");
219   fprintf(logfile, "============================\n");
220 }
221 
optimize_cdf_table_var_modes_4d(aom_count_type * counts,FILE * const probsfile,int dim_of_cts,int * cts_each_dim,int * modes_each_ctx,char * prefix)222 static void optimize_cdf_table_var_modes_4d(aom_count_type *counts,
223                                             FILE *const probsfile,
224                                             int dim_of_cts, int *cts_each_dim,
225                                             int *modes_each_ctx, char *prefix) {
226   aom_count_type *ct_ptr = counts;
227 
228   assert(dim_of_cts == 4);
229   (void)dim_of_cts;
230 
231   fprintf(probsfile, "%s = {\n", prefix);
232   fprintf(logfile, "%s\n", prefix);
233 
234   for (int d0_idx = 0; d0_idx < cts_each_dim[0]; ++d0_idx) {
235     fprintf(probsfile, "%*c{\n", SPACES_PER_TAB, ' ');
236     for (int d1_idx = 0; d1_idx < cts_each_dim[1]; ++d1_idx) {
237       fprintf(probsfile, "%*c{\n", 2 * SPACES_PER_TAB, ' ');
238       for (int d2_idx = 0; d2_idx < cts_each_dim[2]; ++d2_idx) {
239         int num_of_modes = modes_each_ctx[d0_idx];
240 
241         if (num_of_modes > 0) {
242           fprintf(probsfile, "%*c{ ", 3 * SPACES_PER_TAB, ' ');
243           parse_counts_for_cdf_opt(&ct_ptr, probsfile, 0, 1, &num_of_modes);
244           ct_ptr += cts_each_dim[3] - num_of_modes;
245           fprintf(probsfile, " },\n");
246         } else {
247           fprintf(probsfile, "%*c{ 0 },\n", 3 * SPACES_PER_TAB, ' ');
248           fprintf(logfile, "dummy cdf, no need to optimize\n");
249           ct_ptr += cts_each_dim[3];
250         }
251       }
252       fprintf(probsfile, "%*c},\n", 2 * SPACES_PER_TAB, ' ');
253     }
254     fprintf(probsfile, "%*c},\n", SPACES_PER_TAB, ' ');
255   }
256   fprintf(probsfile, "};\n\n");
257   fprintf(logfile, "============================\n");
258 }
259 
main(int argc,const char ** argv)260 int main(int argc, const char **argv) {
261   if (argc < 2) {
262     fprintf(stderr, "Please specify the input stats file!\n");
263     exit(EXIT_FAILURE);
264   }
265 
266   FILE *const statsfile = fopen(argv[1], "rb");
267   if (statsfile == NULL) {
268     fprintf(stderr, "Failed to open input file!\n");
269     exit(EXIT_FAILURE);
270   }
271 
272   FRAME_COUNTS fc;
273   const size_t bytes = fread(&fc, sizeof(FRAME_COUNTS), 1, statsfile);
274   if (!bytes) {
275     fclose(statsfile);
276     return 1;
277   }
278 
279   FILE *const probsfile = fopen("optimized_probs.c", "w");
280   if (probsfile == NULL) {
281     fprintf(stderr,
282             "Failed to create output file for optimized entropy tables!\n");
283     exit(EXIT_FAILURE);
284   }
285 
286   logfile = fopen("aom_entropy_optimizer_parsed_counts.log", "w");
287   if (logfile == NULL) {
288     fprintf(stderr, "Failed to create log file for parsed counts!\n");
289     exit(EXIT_FAILURE);
290   }
291 
292   int cts_each_dim[10];
293 
294   /* Intra mode (keyframe luma) */
295   cts_each_dim[0] = KF_MODE_CONTEXTS;
296   cts_each_dim[1] = KF_MODE_CONTEXTS;
297   cts_each_dim[2] = INTRA_MODES;
298   optimize_cdf_table(&fc.kf_y_mode[0][0][0], probsfile, 3, cts_each_dim,
299                      "const aom_cdf_prob\n"
300                      "default_kf_y_mode_cdf[KF_MODE_CONTEXTS][KF_MODE_CONTEXTS]"
301                      "[CDF_SIZE(INTRA_MODES)]");
302 
303   cts_each_dim[0] = DIRECTIONAL_MODES;
304   cts_each_dim[1] = 2 * MAX_ANGLE_DELTA + 1;
305   optimize_cdf_table(&fc.angle_delta[0][0], probsfile, 2, cts_each_dim,
306                      "static const aom_cdf_prob default_angle_delta_cdf"
307                      "[DIRECTIONAL_MODES][CDF_SIZE(2 * MAX_ANGLE_DELTA + 1)]");
308 
309   /* Intra mode (non-keyframe luma) */
310   cts_each_dim[0] = BLOCK_SIZE_GROUPS;
311   cts_each_dim[1] = INTRA_MODES;
312   optimize_cdf_table(
313       &fc.y_mode[0][0], probsfile, 2, cts_each_dim,
314       "static const aom_cdf_prob\n"
315       "default_if_y_mode_cdf[BLOCK_SIZE_GROUPS][CDF_SIZE(INTRA_MODES)]");
316 
317   /* Intra mode (chroma) */
318   cts_each_dim[0] = CFL_ALLOWED_TYPES;
319   cts_each_dim[1] = INTRA_MODES;
320   cts_each_dim[2] = UV_INTRA_MODES;
321   optimize_uv_mode(&fc.uv_mode[0][0][0], probsfile, 3, cts_each_dim,
322                    "static const aom_cdf_prob\n"
323                    "default_uv_mode_cdf[CFL_ALLOWED_TYPES][INTRA_MODES]"
324                    "[CDF_SIZE(UV_INTRA_MODES)]");
325 
326   /* block partition */
327   cts_each_dim[0] = PARTITION_CONTEXTS;
328   cts_each_dim[1] = EXT_PARTITION_TYPES;
329   int part_types_each_ctx[PARTITION_CONTEXTS] = { 4,  4,  4,  4,  10, 10, 10,
330                                                   10, 10, 10, 10, 10, 10, 10,
331                                                   10, 10, 8,  8,  8,  8 };
332   optimize_cdf_table_var_modes_2d(
333       &fc.partition[0][0], probsfile, 2, cts_each_dim, part_types_each_ctx,
334       "static const aom_cdf_prob default_partition_cdf[PARTITION_CONTEXTS]"
335       "[CDF_SIZE(EXT_PARTITION_TYPES)]");
336 
337   /* tx type */
338   cts_each_dim[0] = EXT_TX_SETS_INTRA;
339   cts_each_dim[1] = EXT_TX_SIZES;
340   cts_each_dim[2] = INTRA_MODES;
341   cts_each_dim[3] = TX_TYPES;
342   int intra_ext_tx_types_each_ctx[EXT_TX_SETS_INTRA] = { 0, 7, 5 };
343   optimize_cdf_table_var_modes_4d(
344       &fc.intra_ext_tx[0][0][0][0], probsfile, 4, cts_each_dim,
345       intra_ext_tx_types_each_ctx,
346       "static const aom_cdf_prob default_intra_ext_tx_cdf[EXT_TX_SETS_INTRA]"
347       "[EXT_TX_SIZES][INTRA_MODES][CDF_SIZE(TX_TYPES)]");
348 
349   cts_each_dim[0] = EXT_TX_SETS_INTER;
350   cts_each_dim[1] = EXT_TX_SIZES;
351   cts_each_dim[2] = TX_TYPES;
352   int inter_ext_tx_types_each_ctx[EXT_TX_SETS_INTER] = { 0, 16, 12, 2 };
353   optimize_cdf_table_var_modes_3d(
354       &fc.inter_ext_tx[0][0][0], probsfile, 3, cts_each_dim,
355       inter_ext_tx_types_each_ctx,
356       "static const aom_cdf_prob default_inter_ext_tx_cdf[EXT_TX_SETS_INTER]"
357       "[EXT_TX_SIZES][CDF_SIZE(TX_TYPES)]");
358 
359   /* Chroma from Luma */
360   cts_each_dim[0] = CFL_JOINT_SIGNS;
361   optimize_cdf_table(&fc.cfl_sign[0], probsfile, 1, cts_each_dim,
362                      "static const aom_cdf_prob\n"
363                      "default_cfl_sign_cdf[CDF_SIZE(CFL_JOINT_SIGNS)]");
364   cts_each_dim[0] = CFL_ALPHA_CONTEXTS;
365   cts_each_dim[1] = CFL_ALPHABET_SIZE;
366   optimize_cdf_table(&fc.cfl_alpha[0][0], probsfile, 2, cts_each_dim,
367                      "static const aom_cdf_prob\n"
368                      "default_cfl_alpha_cdf[CFL_ALPHA_CONTEXTS]"
369                      "[CDF_SIZE(CFL_ALPHABET_SIZE)]");
370 
371   /* Interpolation filter */
372   cts_each_dim[0] = SWITCHABLE_FILTER_CONTEXTS;
373   cts_each_dim[1] = SWITCHABLE_FILTERS;
374   optimize_cdf_table(&fc.switchable_interp[0][0], probsfile, 2, cts_each_dim,
375                      "static const aom_cdf_prob\n"
376                      "default_switchable_interp_cdf[SWITCHABLE_FILTER_CONTEXTS]"
377                      "[CDF_SIZE(SWITCHABLE_FILTERS)]");
378 
379   /* Motion vector referencing */
380   cts_each_dim[0] = NEWMV_MODE_CONTEXTS;
381   cts_each_dim[1] = 2;
382   optimize_cdf_table(&fc.newmv_mode[0][0], probsfile, 2, cts_each_dim,
383                      "static const aom_cdf_prob "
384                      "default_newmv_cdf[NEWMV_MODE_CONTEXTS][CDF_SIZE(2)]");
385 
386   cts_each_dim[0] = GLOBALMV_MODE_CONTEXTS;
387   cts_each_dim[1] = 2;
388   optimize_cdf_table(&fc.zeromv_mode[0][0], probsfile, 2, cts_each_dim,
389                      "static const aom_cdf_prob "
390                      "default_zeromv_cdf[GLOBALMV_MODE_CONTEXTS][CDF_SIZE(2)]");
391 
392   cts_each_dim[0] = REFMV_MODE_CONTEXTS;
393   cts_each_dim[1] = 2;
394   optimize_cdf_table(&fc.refmv_mode[0][0], probsfile, 2, cts_each_dim,
395                      "static const aom_cdf_prob "
396                      "default_refmv_cdf[REFMV_MODE_CONTEXTS][CDF_SIZE(2)]");
397 
398   cts_each_dim[0] = DRL_MODE_CONTEXTS;
399   cts_each_dim[1] = 2;
400   optimize_cdf_table(&fc.drl_mode[0][0], probsfile, 2, cts_each_dim,
401                      "static const aom_cdf_prob "
402                      "default_drl_cdf[DRL_MODE_CONTEXTS][CDF_SIZE(2)]");
403 
404   /* ext_inter experiment */
405   /* New compound mode */
406   cts_each_dim[0] = INTER_MODE_CONTEXTS;
407   cts_each_dim[1] = INTER_COMPOUND_MODES;
408   optimize_cdf_table(&fc.inter_compound_mode[0][0], probsfile, 2, cts_each_dim,
409                      "static const aom_cdf_prob\n"
410                      "default_inter_compound_mode_cdf[INTER_MODE_CONTEXTS][CDF_"
411                      "SIZE(INTER_COMPOUND_MODES)]");
412 
413   /* Interintra */
414   cts_each_dim[0] = BLOCK_SIZE_GROUPS;
415   cts_each_dim[1] = 2;
416   optimize_cdf_table(&fc.interintra[0][0], probsfile, 2, cts_each_dim,
417                      "static const aom_cdf_prob "
418                      "default_interintra_cdf[BLOCK_SIZE_GROUPS][CDF_SIZE(2)]");
419 
420   cts_each_dim[0] = BLOCK_SIZE_GROUPS;
421   cts_each_dim[1] = INTERINTRA_MODES;
422   optimize_cdf_table(&fc.interintra_mode[0][0], probsfile, 2, cts_each_dim,
423                      "static const aom_cdf_prob\n"
424                      "default_interintra_mode_cdf[BLOCK_SIZE_GROUPS][CDF_SIZE("
425                      "INTERINTRA_MODES)]");
426 
427   cts_each_dim[0] = BLOCK_SIZES_ALL;
428   cts_each_dim[1] = 2;
429   optimize_cdf_table(
430       &fc.wedge_interintra[0][0], probsfile, 2, cts_each_dim,
431       "static const aom_cdf_prob\n"
432       "default_wedge_interintra_cdf[BLOCK_SIZES_ALL][CDF_SIZE(2)]");
433 
434   /* Compound type */
435   cts_each_dim[0] = BLOCK_SIZES_ALL;
436   cts_each_dim[1] = COMPOUND_TYPES - 1;
437   optimize_cdf_table(&fc.compound_type[0][0], probsfile, 2, cts_each_dim,
438                      "static const aom_cdf_prob default_compound_type_cdf"
439                      "[BLOCK_SIZES_ALL][CDF_SIZE(COMPOUND_TYPES - 1)]");
440 
441   cts_each_dim[0] = BLOCK_SIZES_ALL;
442   cts_each_dim[1] = 16;
443   optimize_cdf_table(&fc.wedge_idx[0][0], probsfile, 2, cts_each_dim,
444                      "static const aom_cdf_prob "
445                      "default_wedge_idx_cdf[BLOCK_SIZES_ALL][CDF_SIZE(16)]");
446 
447   /* motion_var and warped_motion experiments */
448   cts_each_dim[0] = BLOCK_SIZES_ALL;
449   cts_each_dim[1] = MOTION_MODES;
450   optimize_cdf_table(
451       &fc.motion_mode[0][0], probsfile, 2, cts_each_dim,
452       "static const aom_cdf_prob\n"
453       "default_motion_mode_cdf[BLOCK_SIZES_ALL][CDF_SIZE(MOTION_MODES)]");
454   cts_each_dim[0] = BLOCK_SIZES_ALL;
455   cts_each_dim[1] = 2;
456   optimize_cdf_table(&fc.obmc[0][0], probsfile, 2, cts_each_dim,
457                      "static const aom_cdf_prob "
458                      "default_obmc_cdf[BLOCK_SIZES_ALL][CDF_SIZE(2)]");
459 
460   /* Intra/inter flag */
461   cts_each_dim[0] = INTRA_INTER_CONTEXTS;
462   cts_each_dim[1] = 2;
463   optimize_cdf_table(
464       &fc.intra_inter[0][0], probsfile, 2, cts_each_dim,
465       "static const aom_cdf_prob\n"
466       "default_intra_inter_cdf[INTRA_INTER_CONTEXTS][CDF_SIZE(2)]");
467 
468   /* Single/comp ref flag */
469   cts_each_dim[0] = COMP_INTER_CONTEXTS;
470   cts_each_dim[1] = 2;
471   optimize_cdf_table(
472       &fc.comp_inter[0][0], probsfile, 2, cts_each_dim,
473       "static const aom_cdf_prob\n"
474       "default_comp_inter_cdf[COMP_INTER_CONTEXTS][CDF_SIZE(2)]");
475 
476   /* ext_comp_refs experiment */
477   cts_each_dim[0] = COMP_REF_TYPE_CONTEXTS;
478   cts_each_dim[1] = 2;
479   optimize_cdf_table(
480       &fc.comp_ref_type[0][0], probsfile, 2, cts_each_dim,
481       "static const aom_cdf_prob\n"
482       "default_comp_ref_type_cdf[COMP_REF_TYPE_CONTEXTS][CDF_SIZE(2)]");
483 
484   cts_each_dim[0] = UNI_COMP_REF_CONTEXTS;
485   cts_each_dim[1] = UNIDIR_COMP_REFS - 1;
486   cts_each_dim[2] = 2;
487   optimize_cdf_table(&fc.uni_comp_ref[0][0][0], probsfile, 3, cts_each_dim,
488                      "static const aom_cdf_prob\n"
489                      "default_uni_comp_ref_cdf[UNI_COMP_REF_CONTEXTS][UNIDIR_"
490                      "COMP_REFS - 1][CDF_SIZE(2)]");
491 
492   /* Reference frame (single ref) */
493   cts_each_dim[0] = REF_CONTEXTS;
494   cts_each_dim[1] = SINGLE_REFS - 1;
495   cts_each_dim[2] = 2;
496   optimize_cdf_table(
497       &fc.single_ref[0][0][0], probsfile, 3, cts_each_dim,
498       "static const aom_cdf_prob\n"
499       "default_single_ref_cdf[REF_CONTEXTS][SINGLE_REFS - 1][CDF_SIZE(2)]");
500 
501   /* ext_refs experiment */
502   cts_each_dim[0] = REF_CONTEXTS;
503   cts_each_dim[1] = FWD_REFS - 1;
504   cts_each_dim[2] = 2;
505   optimize_cdf_table(
506       &fc.comp_ref[0][0][0], probsfile, 3, cts_each_dim,
507       "static const aom_cdf_prob\n"
508       "default_comp_ref_cdf[REF_CONTEXTS][FWD_REFS - 1][CDF_SIZE(2)]");
509 
510   cts_each_dim[0] = REF_CONTEXTS;
511   cts_each_dim[1] = BWD_REFS - 1;
512   cts_each_dim[2] = 2;
513   optimize_cdf_table(
514       &fc.comp_bwdref[0][0][0], probsfile, 3, cts_each_dim,
515       "static const aom_cdf_prob\n"
516       "default_comp_bwdref_cdf[REF_CONTEXTS][BWD_REFS - 1][CDF_SIZE(2)]");
517 
518   /* palette */
519   cts_each_dim[0] = PALATTE_BSIZE_CTXS;
520   cts_each_dim[1] = PALETTE_SIZES;
521   optimize_cdf_table(&fc.palette_y_size[0][0], probsfile, 2, cts_each_dim,
522                      "const aom_cdf_prob default_palette_y_size_cdf"
523                      "[PALATTE_BSIZE_CTXS][CDF_SIZE(PALETTE_SIZES)]");
524 
525   cts_each_dim[0] = PALATTE_BSIZE_CTXS;
526   cts_each_dim[1] = PALETTE_SIZES;
527   optimize_cdf_table(&fc.palette_uv_size[0][0], probsfile, 2, cts_each_dim,
528                      "const aom_cdf_prob default_palette_uv_size_cdf"
529                      "[PALATTE_BSIZE_CTXS][CDF_SIZE(PALETTE_SIZES)]");
530 
531   cts_each_dim[0] = PALATTE_BSIZE_CTXS;
532   cts_each_dim[1] = PALETTE_Y_MODE_CONTEXTS;
533   cts_each_dim[2] = 2;
534   optimize_cdf_table(&fc.palette_y_mode[0][0][0], probsfile, 3, cts_each_dim,
535                      "const aom_cdf_prob default_palette_y_mode_cdf"
536                      "[PALATTE_BSIZE_CTXS][PALETTE_Y_MODE_CONTEXTS]"
537                      "[CDF_SIZE(2)]");
538 
539   cts_each_dim[0] = PALETTE_UV_MODE_CONTEXTS;
540   cts_each_dim[1] = 2;
541   optimize_cdf_table(&fc.palette_uv_mode[0][0], probsfile, 2, cts_each_dim,
542                      "const aom_cdf_prob default_palette_uv_mode_cdf"
543                      "[PALETTE_UV_MODE_CONTEXTS][CDF_SIZE(2)]");
544 
545   cts_each_dim[0] = PALETTE_SIZES;
546   cts_each_dim[1] = PALETTE_COLOR_INDEX_CONTEXTS;
547   cts_each_dim[2] = PALETTE_COLORS;
548   int palette_color_indexes_each_ctx[PALETTE_SIZES] = { 2, 3, 4, 5, 6, 7, 8 };
549   optimize_cdf_table_var_modes_3d(
550       &fc.palette_y_color_index[0][0][0], probsfile, 3, cts_each_dim,
551       palette_color_indexes_each_ctx,
552       "const aom_cdf_prob default_palette_y_color_index_cdf[PALETTE_SIZES]"
553       "[PALETTE_COLOR_INDEX_CONTEXTS][CDF_SIZE(PALETTE_COLORS)]");
554 
555   cts_each_dim[0] = PALETTE_SIZES;
556   cts_each_dim[1] = PALETTE_COLOR_INDEX_CONTEXTS;
557   cts_each_dim[2] = PALETTE_COLORS;
558   optimize_cdf_table_var_modes_3d(
559       &fc.palette_uv_color_index[0][0][0], probsfile, 3, cts_each_dim,
560       palette_color_indexes_each_ctx,
561       "const aom_cdf_prob default_palette_uv_color_index_cdf[PALETTE_SIZES]"
562       "[PALETTE_COLOR_INDEX_CONTEXTS][CDF_SIZE(PALETTE_COLORS)]");
563 
564   /* Transform size */
565   cts_each_dim[0] = TXFM_PARTITION_CONTEXTS;
566   cts_each_dim[1] = 2;
567   optimize_cdf_table(
568       &fc.txfm_partition[0][0], probsfile, 2, cts_each_dim,
569       "static const aom_cdf_prob\n"
570       "default_txfm_partition_cdf[TXFM_PARTITION_CONTEXTS][CDF_SIZE(2)]");
571 
572   /* Skip flag */
573   cts_each_dim[0] = SKIP_CONTEXTS;
574   cts_each_dim[1] = 2;
575   optimize_cdf_table(&fc.skip_txfm[0][0], probsfile, 2, cts_each_dim,
576                      "static const aom_cdf_prob "
577                      "default_skip_txfm_cdfs[SKIP_CONTEXTS][CDF_SIZE(2)]");
578 
579   /* Skip mode flag */
580   cts_each_dim[0] = SKIP_MODE_CONTEXTS;
581   cts_each_dim[1] = 2;
582   optimize_cdf_table(&fc.skip_mode[0][0], probsfile, 2, cts_each_dim,
583                      "static const aom_cdf_prob "
584                      "default_skip_mode_cdfs[SKIP_MODE_CONTEXTS][CDF_SIZE(2)]");
585 
586   /* joint compound flag */
587   cts_each_dim[0] = COMP_INDEX_CONTEXTS;
588   cts_each_dim[1] = 2;
589   optimize_cdf_table(&fc.compound_index[0][0], probsfile, 2, cts_each_dim,
590                      "static const aom_cdf_prob default_compound_idx_cdfs"
591                      "[COMP_INDEX_CONTEXTS][CDF_SIZE(2)]");
592 
593   cts_each_dim[0] = COMP_GROUP_IDX_CONTEXTS;
594   cts_each_dim[1] = 2;
595   optimize_cdf_table(&fc.comp_group_idx[0][0], probsfile, 2, cts_each_dim,
596                      "static const aom_cdf_prob default_comp_group_idx_cdfs"
597                      "[COMP_GROUP_IDX_CONTEXTS][CDF_SIZE(2)]");
598 
599   /* intrabc */
600   cts_each_dim[0] = 2;
601   optimize_cdf_table(
602       &fc.intrabc[0], probsfile, 1, cts_each_dim,
603       "static const aom_cdf_prob default_intrabc_cdf[CDF_SIZE(2)]");
604 
605   /* filter_intra experiment */
606   cts_each_dim[0] = FILTER_INTRA_MODES;
607   optimize_cdf_table(
608       &fc.filter_intra_mode[0], probsfile, 1, cts_each_dim,
609       "static const aom_cdf_prob "
610       "default_filter_intra_mode_cdf[CDF_SIZE(FILTER_INTRA_MODES)]");
611 
612   cts_each_dim[0] = BLOCK_SIZES_ALL;
613   cts_each_dim[1] = 2;
614   optimize_cdf_table(&fc.filter_intra[0][0], probsfile, 2, cts_each_dim,
615                      "static const aom_cdf_prob "
616                      "default_filter_intra_cdfs[BLOCK_SIZES_ALL][CDF_SIZE(2)]");
617 
618   /* restoration type */
619   cts_each_dim[0] = RESTORE_SWITCHABLE_TYPES;
620   optimize_cdf_table(&fc.switchable_restore[0], probsfile, 1, cts_each_dim,
621                      "static const aom_cdf_prob default_switchable_restore_cdf"
622                      "[CDF_SIZE(RESTORE_SWITCHABLE_TYPES)]");
623 
624   cts_each_dim[0] = 2;
625   optimize_cdf_table(&fc.wiener_restore[0], probsfile, 1, cts_each_dim,
626                      "static const aom_cdf_prob default_wiener_restore_cdf"
627                      "[CDF_SIZE(2)]");
628 
629   cts_each_dim[0] = 2;
630   optimize_cdf_table(&fc.sgrproj_restore[0], probsfile, 1, cts_each_dim,
631                      "static const aom_cdf_prob default_sgrproj_restore_cdf"
632                      "[CDF_SIZE(2)]");
633 
634   /* intra tx size */
635   cts_each_dim[0] = MAX_TX_CATS;
636   cts_each_dim[1] = TX_SIZE_CONTEXTS;
637   cts_each_dim[2] = MAX_TX_DEPTH + 1;
638   int intra_tx_sizes_each_ctx[MAX_TX_CATS] = { 2, 3, 3, 3 };
639   optimize_cdf_table_var_modes_3d(
640       &fc.intra_tx_size[0][0][0], probsfile, 3, cts_each_dim,
641       intra_tx_sizes_each_ctx,
642       "static const aom_cdf_prob default_tx_size_cdf"
643       "[MAX_TX_CATS][TX_SIZE_CONTEXTS][CDF_SIZE(MAX_TX_DEPTH + 1)]");
644 
645   /* transform coding */
646   cts_each_dim[0] = TOKEN_CDF_Q_CTXS;
647   cts_each_dim[1] = TX_SIZES;
648   cts_each_dim[2] = TXB_SKIP_CONTEXTS;
649   cts_each_dim[3] = 2;
650   optimize_cdf_table(&fc.txb_skip[0][0][0][0], probsfile, 4, cts_each_dim,
651                      "static const aom_cdf_prob "
652                      "av1_default_txb_skip_cdfs[TOKEN_CDF_Q_CTXS][TX_SIZES]"
653                      "[TXB_SKIP_CONTEXTS][CDF_SIZE(2)]");
654 
655   cts_each_dim[0] = TOKEN_CDF_Q_CTXS;
656   cts_each_dim[1] = TX_SIZES;
657   cts_each_dim[2] = PLANE_TYPES;
658   cts_each_dim[3] = EOB_COEF_CONTEXTS;
659   cts_each_dim[4] = 2;
660   optimize_cdf_table(
661       &fc.eob_extra[0][0][0][0][0], probsfile, 5, cts_each_dim,
662       "static const aom_cdf_prob av1_default_eob_extra_cdfs "
663       "[TOKEN_CDF_Q_CTXS][TX_SIZES][PLANE_TYPES][EOB_COEF_CONTEXTS]"
664       "[CDF_SIZE(2)]");
665 
666   cts_each_dim[0] = TOKEN_CDF_Q_CTXS;
667   cts_each_dim[1] = PLANE_TYPES;
668   cts_each_dim[2] = 2;
669   cts_each_dim[3] = 5;
670   optimize_cdf_table(&fc.eob_multi16[0][0][0][0], probsfile, 4, cts_each_dim,
671                      "static const aom_cdf_prob av1_default_eob_multi16_cdfs"
672                      "[TOKEN_CDF_Q_CTXS][PLANE_TYPES][2][CDF_SIZE(5)]");
673 
674   cts_each_dim[0] = TOKEN_CDF_Q_CTXS;
675   cts_each_dim[1] = PLANE_TYPES;
676   cts_each_dim[2] = 2;
677   cts_each_dim[3] = 6;
678   optimize_cdf_table(&fc.eob_multi32[0][0][0][0], probsfile, 4, cts_each_dim,
679                      "static const aom_cdf_prob av1_default_eob_multi32_cdfs"
680                      "[TOKEN_CDF_Q_CTXS][PLANE_TYPES][2][CDF_SIZE(6)]");
681 
682   cts_each_dim[0] = TOKEN_CDF_Q_CTXS;
683   cts_each_dim[1] = PLANE_TYPES;
684   cts_each_dim[2] = 2;
685   cts_each_dim[3] = 7;
686   optimize_cdf_table(&fc.eob_multi64[0][0][0][0], probsfile, 4, cts_each_dim,
687                      "static const aom_cdf_prob av1_default_eob_multi64_cdfs"
688                      "[TOKEN_CDF_Q_CTXS][PLANE_TYPES][2][CDF_SIZE(7)]");
689 
690   cts_each_dim[0] = TOKEN_CDF_Q_CTXS;
691   cts_each_dim[1] = PLANE_TYPES;
692   cts_each_dim[2] = 2;
693   cts_each_dim[3] = 8;
694   optimize_cdf_table(&fc.eob_multi128[0][0][0][0], probsfile, 4, cts_each_dim,
695                      "static const aom_cdf_prob av1_default_eob_multi128_cdfs"
696                      "[TOKEN_CDF_Q_CTXS][PLANE_TYPES][2][CDF_SIZE(8)]");
697 
698   cts_each_dim[0] = TOKEN_CDF_Q_CTXS;
699   cts_each_dim[1] = PLANE_TYPES;
700   cts_each_dim[2] = 2;
701   cts_each_dim[3] = 9;
702   optimize_cdf_table(&fc.eob_multi256[0][0][0][0], probsfile, 4, cts_each_dim,
703                      "static const aom_cdf_prob av1_default_eob_multi256_cdfs"
704                      "[TOKEN_CDF_Q_CTXS][PLANE_TYPES][2][CDF_SIZE(9)]");
705 
706   cts_each_dim[0] = TOKEN_CDF_Q_CTXS;
707   cts_each_dim[1] = PLANE_TYPES;
708   cts_each_dim[2] = 2;
709   cts_each_dim[3] = 10;
710   optimize_cdf_table(&fc.eob_multi512[0][0][0][0], probsfile, 4, cts_each_dim,
711                      "static const aom_cdf_prob av1_default_eob_multi512_cdfs"
712                      "[TOKEN_CDF_Q_CTXS][PLANE_TYPES][2][CDF_SIZE(10)]");
713 
714   cts_each_dim[0] = TOKEN_CDF_Q_CTXS;
715   cts_each_dim[1] = PLANE_TYPES;
716   cts_each_dim[2] = 2;
717   cts_each_dim[3] = 11;
718   optimize_cdf_table(&fc.eob_multi1024[0][0][0][0], probsfile, 4, cts_each_dim,
719                      "static const aom_cdf_prob av1_default_eob_multi1024_cdfs"
720                      "[TOKEN_CDF_Q_CTXS][PLANE_TYPES][2][CDF_SIZE(11)]");
721 
722   cts_each_dim[0] = TOKEN_CDF_Q_CTXS;
723   cts_each_dim[1] = TX_SIZES;
724   cts_each_dim[2] = PLANE_TYPES;
725   cts_each_dim[3] = LEVEL_CONTEXTS;
726   cts_each_dim[4] = BR_CDF_SIZE;
727   optimize_cdf_table(&fc.coeff_lps_multi[0][0][0][0][0], probsfile, 5,
728                      cts_each_dim,
729                      "static const aom_cdf_prob "
730                      "av1_default_coeff_lps_multi_cdfs[TOKEN_CDF_Q_CTXS]"
731                      "[TX_SIZES][PLANE_TYPES][LEVEL_CONTEXTS]"
732                      "[CDF_SIZE(BR_CDF_SIZE)]");
733 
734   cts_each_dim[0] = TOKEN_CDF_Q_CTXS;
735   cts_each_dim[1] = TX_SIZES;
736   cts_each_dim[2] = PLANE_TYPES;
737   cts_each_dim[3] = SIG_COEF_CONTEXTS;
738   cts_each_dim[4] = NUM_BASE_LEVELS + 2;
739   optimize_cdf_table(
740       &fc.coeff_base_multi[0][0][0][0][0], probsfile, 5, cts_each_dim,
741       "static const aom_cdf_prob av1_default_coeff_base_multi_cdfs"
742       "[TOKEN_CDF_Q_CTXS][TX_SIZES][PLANE_TYPES][SIG_COEF_CONTEXTS]"
743       "[CDF_SIZE(NUM_BASE_LEVELS + 2)]");
744 
745   cts_each_dim[0] = TOKEN_CDF_Q_CTXS;
746   cts_each_dim[1] = TX_SIZES;
747   cts_each_dim[2] = PLANE_TYPES;
748   cts_each_dim[3] = SIG_COEF_CONTEXTS_EOB;
749   cts_each_dim[4] = NUM_BASE_LEVELS + 1;
750   optimize_cdf_table(
751       &fc.coeff_base_eob_multi[0][0][0][0][0], probsfile, 5, cts_each_dim,
752       "static const aom_cdf_prob av1_default_coeff_base_eob_multi_cdfs"
753       "[TOKEN_CDF_Q_CTXS][TX_SIZES][PLANE_TYPES][SIG_COEF_CONTEXTS_EOB]"
754       "[CDF_SIZE(NUM_BASE_LEVELS + 1)]");
755 
756   fclose(statsfile);
757   fclose(logfile);
758   fclose(probsfile);
759 
760   return 0;
761 }
762