OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2010 The WebM project authors. All Rights Reserved. | 2 * Copyright (c) 2010 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 <assert.h> | 11 #include <assert.h> |
12 #include <limits.h> | 12 #include <limits.h> |
| 13 |
| 14 #include "./vpx_scale_rtcd.h" |
| 15 |
| 16 #include "vpx_mem/vpx_mem.h" |
| 17 |
| 18 #include "vp9/common/vp9_loopfilter.h" |
13 #include "vp9/common/vp9_onyxc_int.h" | 19 #include "vp9/common/vp9_onyxc_int.h" |
| 20 #include "vp9/common/vp9_quant_common.h" |
| 21 |
14 #include "vp9/encoder/vp9_onyx_int.h" | 22 #include "vp9/encoder/vp9_onyx_int.h" |
15 #include "vp9/encoder/vp9_picklpf.h" | 23 #include "vp9/encoder/vp9_picklpf.h" |
16 #include "vp9/encoder/vp9_quantize.h" | 24 #include "vp9/encoder/vp9_quantize.h" |
17 #include "vp9/common/vp9_quant_common.h" | |
18 #include "vpx_mem/vpx_mem.h" | |
19 #include "vpx_scale/vpx_scale.h" | |
20 #include "vp9/common/vp9_alloccommon.h" | |
21 #include "vp9/common/vp9_loopfilter.h" | |
22 #include "./vpx_scale_rtcd.h" | |
23 | 25 |
24 static int get_min_filter_level(VP9_COMP *cpi, int base_qindex) { | 26 static int get_max_filter_level(VP9_COMP *cpi) { |
25 return 0; | |
26 } | |
27 | |
28 static int get_max_filter_level(VP9_COMP *cpi, int base_qindex) { | |
29 return cpi->twopass.section_intra_rating > 8 ? MAX_LOOP_FILTER * 3 / 4 | 27 return cpi->twopass.section_intra_rating > 8 ? MAX_LOOP_FILTER * 3 / 4 |
30 : MAX_LOOP_FILTER; | 28 : MAX_LOOP_FILTER; |
31 } | 29 } |
32 | 30 |
33 // Stub function for now Alt LF not used | |
34 void vp9_set_alt_lf_level(VP9_COMP *cpi, int filt_val) { | |
35 } | |
36 | 31 |
37 static int try_filter_frame(const YV12_BUFFER_CONFIG *sd, VP9_COMP *const cpi, | 32 static int try_filter_frame(const YV12_BUFFER_CONFIG *sd, VP9_COMP *const cpi, |
38 MACROBLOCKD *const xd, VP9_COMMON *const cm, | |
39 int filt_level, int partial_frame) { | 33 int filt_level, int partial_frame) { |
| 34 VP9_COMMON *const cm = &cpi->common; |
40 int filt_err; | 35 int filt_err; |
41 | 36 |
42 vp9_set_alt_lf_level(cpi, filt_level); | 37 vp9_loop_filter_frame(cm, &cpi->mb.e_mbd, filt_level, 1, partial_frame); |
43 vp9_loop_filter_frame(cm, xd, filt_level, 1, partial_frame); | 38 filt_err = vp9_get_y_sse(sd, cm->frame_to_show); |
44 | |
45 filt_err = vp9_calc_ss_err(sd, cm->frame_to_show); | |
46 | 39 |
47 // Re-instate the unfiltered frame | 40 // Re-instate the unfiltered frame |
48 vpx_yv12_copy_y(&cpi->last_frame_uf, cm->frame_to_show); | 41 vpx_yv12_copy_y(&cpi->last_frame_uf, cm->frame_to_show); |
49 | 42 |
50 return filt_err; | 43 return filt_err; |
51 } | 44 } |
52 | 45 |
53 static void search_filter_level(const YV12_BUFFER_CONFIG *sd, VP9_COMP *cpi, | 46 static void search_filter_level(const YV12_BUFFER_CONFIG *sd, VP9_COMP *cpi, |
54 int partial_frame) { | 47 int partial_frame) { |
55 MACROBLOCKD *const xd = &cpi->mb.e_mbd; | |
56 VP9_COMMON *const cm = &cpi->common; | 48 VP9_COMMON *const cm = &cpi->common; |
57 struct loopfilter *const lf = &cm->lf; | 49 struct loopfilter *const lf = &cm->lf; |
58 const int min_filter_level = get_min_filter_level(cpi, cm->base_qindex); | 50 const int min_filter_level = 0; |
59 const int max_filter_level = get_max_filter_level(cpi, cm->base_qindex); | 51 const int max_filter_level = get_max_filter_level(cpi); |
60 int best_err; | 52 int best_err; |
61 int filt_best; | 53 int filt_best; |
62 int filt_direction = 0; | 54 int filt_direction = 0; |
63 // Start the search at the previous frame filter level unless it is now out of | 55 // Start the search at the previous frame filter level unless it is now out of |
64 // range. | 56 // range. |
65 int filt_mid = clamp(lf->filter_level, min_filter_level, max_filter_level); | 57 int filt_mid = clamp(lf->filter_level, min_filter_level, max_filter_level); |
66 int filter_step = filt_mid < 16 ? 4 : filt_mid / 4; | 58 int filter_step = filt_mid < 16 ? 4 : filt_mid / 4; |
67 // Sum squared error at each filter level | 59 // Sum squared error at each filter level |
68 int ss_err[MAX_LOOP_FILTER + 1]; | 60 int ss_err[MAX_LOOP_FILTER + 1]; |
69 | 61 |
70 // Set each entry to -1 | 62 // Set each entry to -1 |
71 vpx_memset(ss_err, 0xFF, sizeof(ss_err)); | 63 vpx_memset(ss_err, 0xFF, sizeof(ss_err)); |
72 | 64 |
73 // Make a copy of the unfiltered / processed recon buffer | 65 // Make a copy of the unfiltered / processed recon buffer |
74 vpx_yv12_copy_y(cm->frame_to_show, &cpi->last_frame_uf); | 66 vpx_yv12_copy_y(cm->frame_to_show, &cpi->last_frame_uf); |
75 | 67 |
76 best_err = try_filter_frame(sd, cpi, xd, cm, filt_mid, partial_frame); | 68 best_err = try_filter_frame(sd, cpi, filt_mid, partial_frame); |
77 filt_best = filt_mid; | 69 filt_best = filt_mid; |
78 ss_err[filt_mid] = best_err; | 70 ss_err[filt_mid] = best_err; |
79 | 71 |
80 while (filter_step > 0) { | 72 while (filter_step > 0) { |
81 const int filt_high = MIN(filt_mid + filter_step, max_filter_level); | 73 const int filt_high = MIN(filt_mid + filter_step, max_filter_level); |
82 const int filt_low = MAX(filt_mid - filter_step, min_filter_level); | 74 const int filt_low = MAX(filt_mid - filter_step, min_filter_level); |
83 int filt_err; | 75 int filt_err; |
84 | 76 |
85 // Bias against raising loop filter in favor of lowering it. | 77 // Bias against raising loop filter in favor of lowering it. |
86 int bias = (best_err >> (15 - (filt_mid / 8))) * filter_step; | 78 int bias = (best_err >> (15 - (filt_mid / 8))) * filter_step; |
87 | 79 |
88 if (cpi->twopass.section_intra_rating < 20) | 80 if (cpi->twopass.section_intra_rating < 20) |
89 bias = bias * cpi->twopass.section_intra_rating / 20; | 81 bias = bias * cpi->twopass.section_intra_rating / 20; |
90 | 82 |
91 // yx, bias less for large block size | 83 // yx, bias less for large block size |
92 if (cm->tx_mode != ONLY_4X4) | 84 if (cm->tx_mode != ONLY_4X4) |
93 bias >>= 1; | 85 bias >>= 1; |
94 | 86 |
95 if (filt_direction <= 0 && filt_low != filt_mid) { | 87 if (filt_direction <= 0 && filt_low != filt_mid) { |
96 // Get Low filter error score | 88 // Get Low filter error score |
97 if (ss_err[filt_low] < 0) { | 89 if (ss_err[filt_low] < 0) { |
98 filt_err = try_filter_frame(sd, cpi, xd, cm, filt_low, partial_frame); | 90 filt_err = try_filter_frame(sd, cpi, filt_low, partial_frame); |
99 ss_err[filt_low] = filt_err; | 91 ss_err[filt_low] = filt_err; |
100 } else { | 92 } else { |
101 filt_err = ss_err[filt_low]; | 93 filt_err = ss_err[filt_low]; |
102 } | 94 } |
103 // If value is close to the best so far then bias towards a lower loop | 95 // If value is close to the best so far then bias towards a lower loop |
104 // filter value. | 96 // filter value. |
105 if ((filt_err - bias) < best_err) { | 97 if ((filt_err - bias) < best_err) { |
106 // Was it actually better than the previous best? | 98 // Was it actually better than the previous best? |
107 if (filt_err < best_err) | 99 if (filt_err < best_err) |
108 best_err = filt_err; | 100 best_err = filt_err; |
109 | 101 |
110 filt_best = filt_low; | 102 filt_best = filt_low; |
111 } | 103 } |
112 } | 104 } |
113 | 105 |
114 // Now look at filt_high | 106 // Now look at filt_high |
115 if (filt_direction >= 0 && filt_high != filt_mid) { | 107 if (filt_direction >= 0 && filt_high != filt_mid) { |
116 if (ss_err[filt_high] < 0) { | 108 if (ss_err[filt_high] < 0) { |
117 filt_err = try_filter_frame(sd, cpi, xd, cm, filt_high, partial_frame); | 109 filt_err = try_filter_frame(sd, cpi, filt_high, partial_frame); |
118 ss_err[filt_high] = filt_err; | 110 ss_err[filt_high] = filt_err; |
119 } else { | 111 } else { |
120 filt_err = ss_err[filt_high]; | 112 filt_err = ss_err[filt_high]; |
121 } | 113 } |
122 // Was it better than the previous best? | 114 // Was it better than the previous best? |
123 if (filt_err < (best_err - bias)) { | 115 if (filt_err < (best_err - bias)) { |
124 best_err = filt_err; | 116 best_err = filt_err; |
125 filt_best = filt_high; | 117 filt_best = filt_high; |
126 } | 118 } |
127 } | 119 } |
128 | 120 |
129 // Half the step distance if the best filter value was the same as last time | 121 // Half the step distance if the best filter value was the same as last time |
130 if (filt_best == filt_mid) { | 122 if (filt_best == filt_mid) { |
131 filter_step = filter_step / 2; | 123 filter_step /= 2; |
132 filt_direction = 0; | 124 filt_direction = 0; |
133 } else { | 125 } else { |
134 filt_direction = (filt_best < filt_mid) ? -1 : 1; | 126 filt_direction = (filt_best < filt_mid) ? -1 : 1; |
135 filt_mid = filt_best; | 127 filt_mid = filt_best; |
136 } | 128 } |
137 } | 129 } |
138 | 130 |
139 lf->filter_level = filt_best; | 131 lf->filter_level = filt_best; |
140 } | 132 } |
141 | 133 |
142 void vp9_pick_filter_level(const YV12_BUFFER_CONFIG *sd, VP9_COMP *cpi, | 134 void vp9_pick_filter_level(const YV12_BUFFER_CONFIG *sd, VP9_COMP *cpi, |
143 int method) { | 135 LPF_PICK_METHOD method) { |
144 VP9_COMMON *const cm = &cpi->common; | 136 VP9_COMMON *const cm = &cpi->common; |
145 struct loopfilter *const lf = &cm->lf; | 137 struct loopfilter *const lf = &cm->lf; |
146 | 138 |
147 lf->sharpness_level = cm->frame_type == KEY_FRAME ? 0 | 139 lf->sharpness_level = cm->frame_type == KEY_FRAME ? 0 |
148 : cpi->oxcf.sharpness; | 140 : cpi->oxcf.sharpness; |
149 | 141 |
150 if (method == 2) { | 142 if (method == LPF_PICK_FROM_Q) { |
151 const int min_filter_level = get_min_filter_level(cpi, cm->base_qindex); | 143 const int min_filter_level = 0; |
152 const int max_filter_level = get_max_filter_level(cpi, cm->base_qindex); | 144 const int max_filter_level = get_max_filter_level(cpi); |
153 const int q = vp9_ac_quant(cm->base_qindex, 0); | 145 const int q = vp9_ac_quant(cm->base_qindex, 0); |
154 // These values were determined by linear fitting the result of the | 146 // These values were determined by linear fitting the result of the |
155 // searched level | 147 // searched level, filt_guess = q * 0.316206 + 3.87252 |
156 // filt_guess = q * 0.316206 + 3.87252 | 148 int filt_guess = ROUND_POWER_OF_TWO(q * 20723 + 1015158, 18); |
157 int filt_guess = (q * 20723 + 1015158 + (1 << 17)) >> 18; | |
158 if (cm->frame_type == KEY_FRAME) | 149 if (cm->frame_type == KEY_FRAME) |
159 filt_guess -= 4; | 150 filt_guess -= 4; |
160 lf->filter_level = clamp(filt_guess, min_filter_level, max_filter_level); | 151 lf->filter_level = clamp(filt_guess, min_filter_level, max_filter_level); |
161 } else { | 152 } else { |
162 search_filter_level(sd, cpi, method == 1); | 153 search_filter_level(sd, cpi, method == LPF_PICK_FROM_SUBIMAGE); |
163 } | 154 } |
164 } | 155 } |
OLD | NEW |