1 /*
2 * Copyright (c) 2016, 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 #include "common/warnings.h"
13
14 #include <assert.h>
15 #include <stdio.h>
16 #include <stdlib.h>
17 #include <string.h>
18
19 #include "aom/aom_encoder.h"
20 #include "apps/aomenc.h"
21 #include "common/tools_common.h"
22
23 static const char quantizer_warning_string[] =
24 "Bad quantizer values. Quantizer values should not be equal, and should "
25 "differ by at least 8.";
26
27 struct WarningListNode {
28 const char *warning_string;
29 struct WarningListNode *next_warning;
30 };
31
32 struct WarningList {
33 struct WarningListNode *warning_node;
34 };
35
add_warning(const char * warning_string,struct WarningList * warning_list)36 static void add_warning(const char *warning_string,
37 struct WarningList *warning_list) {
38 struct WarningListNode **node = &warning_list->warning_node;
39
40 struct WarningListNode *new_node = malloc(sizeof(*new_node));
41 if (new_node == NULL) {
42 fatal("Unable to allocate warning node.");
43 }
44
45 new_node->warning_string = warning_string;
46 new_node->next_warning = NULL;
47
48 while (*node != NULL) node = &(*node)->next_warning;
49
50 *node = new_node;
51 }
52
free_warning_list(struct WarningList * warning_list)53 static void free_warning_list(struct WarningList *warning_list) {
54 while (warning_list->warning_node != NULL) {
55 struct WarningListNode *const node = warning_list->warning_node;
56 warning_list->warning_node = node->next_warning;
57 free(node);
58 }
59 }
60
continue_prompt(int num_warnings)61 static int continue_prompt(int num_warnings) {
62 int c;
63 fprintf(stderr,
64 "%d encoder configuration warning(s). Continue? (y to continue) ",
65 num_warnings);
66 c = getchar();
67 return c == 'y';
68 }
69
check_quantizer(int min_q,int max_q,struct WarningList * warning_list)70 static void check_quantizer(int min_q, int max_q,
71 struct WarningList *warning_list) {
72 const int lossless = min_q == 0 && max_q == 0;
73 if (!lossless && (min_q == max_q || abs(max_q - min_q) < 8))
74 add_warning(quantizer_warning_string, warning_list);
75 }
76
check_encoder_config(int disable_prompt,const struct AvxEncoderConfig * global_config,const struct aom_codec_enc_cfg * stream_config)77 void check_encoder_config(int disable_prompt,
78 const struct AvxEncoderConfig *global_config,
79 const struct aom_codec_enc_cfg *stream_config) {
80 int num_warnings = 0;
81 struct WarningListNode *warning = NULL;
82 struct WarningList warning_list = { 0 };
83 (void)global_config;
84 check_quantizer(stream_config->rc_min_quantizer,
85 stream_config->rc_max_quantizer, &warning_list);
86 /* Count and print warnings. */
87 for (warning = warning_list.warning_node; warning != NULL;
88 warning = warning->next_warning, ++num_warnings) {
89 aom_tools_warn("%s", warning->warning_string);
90 }
91
92 free_warning_list(&warning_list);
93
94 if (num_warnings) {
95 if (!disable_prompt && !continue_prompt(num_warnings)) exit(EXIT_FAILURE);
96 }
97 }
98