OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2014 The WebM project authors. All Rights Reserved. | 2 * Copyright (c) 2014 The WebM project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
11 #include <limits.h> | 11 #include <limits.h> |
12 #include <math.h> | 12 #include <math.h> |
13 | 13 |
14 #include "vp9/encoder/vp9_aq_variance.h" | 14 #include "vp9/encoder/vp9_aq_variance.h" |
15 #include "vp9/encoder/vp9_encodeframe.h" | 15 #include "vp9/encoder/vp9_encodeframe.h" |
16 #include "vp9/common/vp9_seg_common.h" | 16 #include "vp9/common/vp9_seg_common.h" |
17 #include "vp9/encoder/vp9_segmentation.h" | 17 #include "vp9/encoder/vp9_segmentation.h" |
18 | 18 |
19 #define AQ_C_SEGMENTS 3 | 19 #define AQ_C_SEGMENTS 5 |
20 #define AQ_C_STRENGTHS 3 | 20 #define DEFAULT_AQ2_SEG 3 // Neutral Q segment |
21 static const int aq_c_active_segments[AQ_C_STRENGTHS] = {1, 2, 3}; | 21 #define AQ_C_STRENGTHS 3 |
22 static const double aq_c_q_adj_factor[AQ_C_STRENGTHS][AQ_C_SEGMENTS] = | 22 static const double aq_c_q_adj_factor[AQ_C_STRENGTHS][AQ_C_SEGMENTS] = |
23 {{1.0, 1.0, 1.0}, {1.0, 2.0, 1.0}, {1.0, 1.5, 2.5}}; | 23 { {1.75, 1.25, 1.05, 1.00, 0.90}, |
| 24 {2.00, 1.50, 1.15, 1.00, 0.85}, |
| 25 {2.50, 1.75, 1.25, 1.00, 0.80} }; |
24 static const double aq_c_transitions[AQ_C_STRENGTHS][AQ_C_SEGMENTS] = | 26 static const double aq_c_transitions[AQ_C_STRENGTHS][AQ_C_SEGMENTS] = |
25 {{1.0, 1.0, 1.0}, {1.0, 0.25, 0.0}, {1.0, 0.5, 0.25}}; | 27 { {0.15, 0.30, 0.55, 2.00, 100.0}, |
26 static const double aq_c_var_thresholds[AQ_C_SEGMENTS] = {100.0, 12.0, 10.0}; | 28 {0.20, 0.40, 0.65, 2.00, 100.0}, |
| 29 {0.25, 0.50, 0.75, 2.00, 100.0} }; |
| 30 static const double aq_c_var_thresholds[AQ_C_STRENGTHS][AQ_C_SEGMENTS] = |
| 31 { {-4.0, -3.0, -2.0, 100.00, 100.0}, |
| 32 {-3.5, -2.5, -1.5, 100.00, 100.0}, |
| 33 {-3.0, -2.0, -1.0, 100.00, 100.0} }; |
| 34 |
| 35 #define DEFAULT_COMPLEXITY 64 |
| 36 |
27 | 37 |
28 static int get_aq_c_strength(int q_index, vpx_bit_depth_t bit_depth) { | 38 static int get_aq_c_strength(int q_index, vpx_bit_depth_t bit_depth) { |
29 // Approximate base quatizer (truncated to int) | 39 // Approximate base quatizer (truncated to int) |
30 const int base_quant = vp9_ac_quant(q_index, 0, bit_depth) / 4; | 40 const int base_quant = vp9_ac_quant(q_index, 0, bit_depth) / 4; |
31 return (base_quant > 20) + (base_quant > 45); | 41 return (base_quant > 10) + (base_quant > 25); |
32 } | 42 } |
33 | 43 |
34 void vp9_setup_in_frame_q_adj(VP9_COMP *cpi) { | 44 void vp9_setup_in_frame_q_adj(VP9_COMP *cpi) { |
35 VP9_COMMON *const cm = &cpi->common; | 45 VP9_COMMON *const cm = &cpi->common; |
36 struct segmentation *const seg = &cm->seg; | 46 struct segmentation *const seg = &cm->seg; |
37 | 47 |
38 // Make SURE use of floating point in this function is safe. | 48 // Make SURE use of floating point in this function is safe. |
39 vp9_clear_system_state(); | 49 vp9_clear_system_state(); |
40 | 50 |
41 if (cm->frame_type == KEY_FRAME || | 51 if (cm->frame_type == KEY_FRAME || |
42 cpi->refresh_alt_ref_frame || | 52 cpi->refresh_alt_ref_frame || |
43 (cpi->refresh_golden_frame && !cpi->rc.is_src_frame_alt_ref)) { | 53 (cpi->refresh_golden_frame && !cpi->rc.is_src_frame_alt_ref)) { |
44 int segment; | 54 int segment; |
45 const int aq_strength = get_aq_c_strength(cm->base_qindex, cm->bit_depth); | 55 const int aq_strength = get_aq_c_strength(cm->base_qindex, cm->bit_depth); |
46 const int active_segments = aq_c_active_segments[aq_strength]; | |
47 | 56 |
48 // Clear down the segment map. | 57 // Clear down the segment map. |
49 vpx_memset(cpi->segmentation_map, 0, cm->mi_rows * cm->mi_cols); | 58 vpx_memset(cpi->segmentation_map, DEFAULT_AQ2_SEG, |
50 | 59 cm->mi_rows * cm->mi_cols); |
51 // Clear down the complexity map used for rd. | |
52 vpx_memset(cpi->complexity_map, 0, cm->mi_rows * cm->mi_cols); | |
53 | 60 |
54 vp9_clearall_segfeatures(seg); | 61 vp9_clearall_segfeatures(seg); |
55 | 62 |
56 // Segmentation only makes sense if the target bits per SB is above a | 63 // Segmentation only makes sense if the target bits per SB is above a |
57 // threshold. Below this the overheads will usually outweigh any benefit. | 64 // threshold. Below this the overheads will usually outweigh any benefit. |
58 if (cpi->rc.sb64_target_rate < 256) { | 65 if (cpi->rc.sb64_target_rate < 256) { |
59 vp9_disable_segmentation(seg); | 66 vp9_disable_segmentation(seg); |
60 return; | 67 return; |
61 } | 68 } |
62 | 69 |
63 vp9_enable_segmentation(seg); | 70 vp9_enable_segmentation(seg); |
64 | 71 |
65 // Select delta coding method. | 72 // Select delta coding method. |
66 seg->abs_delta = SEGMENT_DELTADATA; | 73 seg->abs_delta = SEGMENT_DELTADATA; |
67 | 74 |
68 // Segment 0 "Q" feature is disabled so it defaults to the baseline Q. | 75 // Default segment "Q" feature is disabled so it defaults to the baseline Q. |
69 vp9_disable_segfeature(seg, 0, SEG_LVL_ALT_Q); | 76 vp9_disable_segfeature(seg, DEFAULT_AQ2_SEG, SEG_LVL_ALT_Q); |
70 | 77 |
71 // Use some of the segments for in frame Q adjustment. | 78 // Use some of the segments for in frame Q adjustment. |
72 for (segment = 1; segment < active_segments; ++segment) { | 79 for (segment = 0; segment < AQ_C_SEGMENTS; ++segment) { |
73 int qindex_delta = | 80 int qindex_delta; |
74 vp9_compute_qdelta_by_rate(&cpi->rc, cm->frame_type, cm->base_qindex, | 81 |
75 aq_c_q_adj_factor[aq_strength][segment], | 82 if (segment == DEFAULT_AQ2_SEG) |
76 cm->bit_depth); | 83 continue; |
| 84 |
| 85 qindex_delta = |
| 86 vp9_compute_qdelta_by_rate(&cpi->rc, cm->frame_type, cm->base_qindex, |
| 87 aq_c_q_adj_factor[aq_strength][segment], |
| 88 cm->bit_depth); |
| 89 |
77 | 90 |
78 // For AQ complexity mode, we dont allow Q0 in a segment if the base | 91 // For AQ complexity mode, we dont allow Q0 in a segment if the base |
79 // Q is not 0. Q0 (lossless) implies 4x4 only and in AQ mode 2 a segment | 92 // Q is not 0. Q0 (lossless) implies 4x4 only and in AQ mode 2 a segment |
80 // Q delta is sometimes applied without going back around the rd loop. | 93 // Q delta is sometimes applied without going back around the rd loop. |
81 // This could lead to an illegal combination of partition size and q. | 94 // This could lead to an illegal combination of partition size and q. |
82 if ((cm->base_qindex != 0) && ((cm->base_qindex + qindex_delta) == 0)) { | 95 if ((cm->base_qindex != 0) && ((cm->base_qindex + qindex_delta) == 0)) { |
83 qindex_delta = -cm->base_qindex + 1; | 96 qindex_delta = -cm->base_qindex + 1; |
84 } | 97 } |
85 if ((cm->base_qindex + qindex_delta) > 0) { | 98 if ((cm->base_qindex + qindex_delta) > 0) { |
86 vp9_enable_segfeature(seg, segment, SEG_LVL_ALT_Q); | 99 vp9_enable_segfeature(seg, segment, SEG_LVL_ALT_Q); |
87 vp9_set_segdata(seg, segment, SEG_LVL_ALT_Q, qindex_delta); | 100 vp9_set_segdata(seg, segment, SEG_LVL_ALT_Q, qindex_delta); |
88 } | 101 } |
89 } | 102 } |
90 } | 103 } |
91 } | 104 } |
92 | 105 |
93 // Select a segment for the current SB64 block. | 106 #define DEFAULT_LV_THRESH 10.0 |
| 107 #define MIN_DEFAULT_LV_THRESH 8.0 |
| 108 #define VAR_STRENGTH_STEP 0.25 |
| 109 // Select a segment for the current block. |
94 // The choice of segment for a block depends on the ratio of the projected | 110 // The choice of segment for a block depends on the ratio of the projected |
95 // bits for the block vs a target average. | 111 // bits for the block vs a target average and its spatial complexity. |
96 // An "aq_strength" value determines how many segments are supported, | 112 void vp9_caq_select_segment(VP9_COMP *cpi, MACROBLOCK *mb, BLOCK_SIZE bs, |
97 // the set of transition points to use and the extent of the quantizer | 113 int mi_row, int mi_col, int projected_rate) { |
98 // adjustment for each segment (configured in vp9_setup_in_frame_q_adj()). | |
99 void vp9_select_in_frame_q_segment(VP9_COMP *cpi, MACROBLOCK *mb, | |
100 BLOCK_SIZE bs, | |
101 int mi_row, int mi_col, | |
102 int output_enabled, int projected_rate) { | |
103 VP9_COMMON *const cm = &cpi->common; | 114 VP9_COMMON *const cm = &cpi->common; |
104 | 115 |
105 const int mi_offset = mi_row * cm->mi_cols + mi_col; | 116 const int mi_offset = mi_row * cm->mi_cols + mi_col; |
106 const int bw = num_8x8_blocks_wide_lookup[BLOCK_64X64]; | 117 const int bw = num_8x8_blocks_wide_lookup[BLOCK_64X64]; |
107 const int bh = num_8x8_blocks_high_lookup[BLOCK_64X64]; | 118 const int bh = num_8x8_blocks_high_lookup[BLOCK_64X64]; |
108 const int xmis = MIN(cm->mi_cols - mi_col, bw); | 119 const int xmis = MIN(cm->mi_cols - mi_col, num_8x8_blocks_wide_lookup[bs]); |
109 const int ymis = MIN(cm->mi_rows - mi_row, bh); | 120 const int ymis = MIN(cm->mi_rows - mi_row, num_8x8_blocks_high_lookup[bs]); |
110 int complexity_metric = 64; | |
111 int x, y; | 121 int x, y; |
112 | 122 int i; |
113 unsigned char segment; | 123 unsigned char segment; |
114 | 124 |
115 if (!output_enabled) { | 125 if (0) { |
116 segment = 0; | 126 segment = DEFAULT_AQ2_SEG; |
117 } else { | 127 } else { |
118 // Rate depends on fraction of a SB64 in frame (xmis * ymis / bw * bh). | 128 // Rate depends on fraction of a SB64 in frame (xmis * ymis / bw * bh). |
119 // It is converted to bits * 256 units. | 129 // It is converted to bits * 256 units. |
120 const int target_rate = (cpi->rc.sb64_target_rate * xmis * ymis * 256) / | 130 const int target_rate = (cpi->rc.sb64_target_rate * xmis * ymis * 256) / |
121 (bw * bh); | 131 (bw * bh); |
| 132 double logvar; |
| 133 double low_var_thresh; |
122 const int aq_strength = get_aq_c_strength(cm->base_qindex, cm->bit_depth); | 134 const int aq_strength = get_aq_c_strength(cm->base_qindex, cm->bit_depth); |
123 const int active_segments = aq_c_active_segments[aq_strength]; | 135 |
124 double logvar; | 136 vp9_clear_system_state(); |
| 137 low_var_thresh = (cpi->oxcf.pass == 2) |
| 138 ? MAX(cpi->twopass.mb_av_energy, MIN_DEFAULT_LV_THRESH) |
| 139 : DEFAULT_LV_THRESH; |
125 | 140 |
126 vp9_setup_src_planes(mb, cpi->Source, mi_row, mi_col); | 141 vp9_setup_src_planes(mb, cpi->Source, mi_row, mi_col); |
127 logvar = vp9_log_block_var(cpi, mb, bs); | 142 logvar = vp9_log_block_var(cpi, mb, bs); |
128 | 143 |
129 // The number of segments considered and the transition points used to | 144 segment = AQ_C_SEGMENTS - 1; // Just in case no break out below. |
130 // select them is determined by the "aq_strength" value. | 145 for (i = 0; i < AQ_C_SEGMENTS; ++i) { |
131 // Currently this loop only supports segments that reduce Q (i.e. where | 146 // Test rate against a threshold value and variance against a threshold. |
132 // there is undershoot. | 147 // Increasing segment number (higher variance and complexity) = higher Q. |
133 // The loop counts down towards segment 0 which is the default segment | |
134 // with no Q adjustment. | |
135 segment = active_segments - 1; | |
136 while (segment > 0) { | |
137 if ((projected_rate < | 148 if ((projected_rate < |
138 target_rate * aq_c_transitions[aq_strength][segment]) && | 149 target_rate * aq_c_transitions[aq_strength][i]) && |
139 (logvar < aq_c_var_thresholds[segment])) { | 150 (logvar < (low_var_thresh + aq_c_var_thresholds[aq_strength][i]))) { |
| 151 segment = i; |
140 break; | 152 break; |
141 } | 153 } |
142 --segment; | |
143 } | |
144 | |
145 if (target_rate > 0) { | |
146 complexity_metric = | |
147 clamp((int)((projected_rate * 64) / target_rate), 16, 255); | |
148 } | 154 } |
149 } | 155 } |
150 | 156 |
151 // Fill in the entires in the segment map corresponding to this SB64. | 157 // Fill in the entires in the segment map corresponding to this SB64. |
152 for (y = 0; y < ymis; y++) { | 158 for (y = 0; y < ymis; y++) { |
153 for (x = 0; x < xmis; x++) { | 159 for (x = 0; x < xmis; x++) { |
154 cpi->segmentation_map[mi_offset + y * cm->mi_cols + x] = segment; | 160 cpi->segmentation_map[mi_offset + y * cm->mi_cols + x] = segment; |
155 cpi->complexity_map[mi_offset + y * cm->mi_cols + x] = | |
156 (unsigned char)complexity_metric; | |
157 } | 161 } |
158 } | 162 } |
159 } | 163 } |
OLD | NEW |