History

avfilter/palettegen: always compute the box variance

The variance computation is simple enough now (since we can use the axis squared errors) that it doesn't need to have a complex lazy computation logic.

Clément Bœsch committed 3 years ago

Commit e49fc1a1 parent 9e5f4941 file · +9 −33Browse files

Unified · Split

libavfilter/vf_palettegen.c+9−33
@@ -135,16 +135,6 @@ static int cmp_color(const void *a, const void *b) · 134 unmodified lines
135 return FFDIFFSIGN(box1->color , box2->color);135 return FFDIFFSIGN(box1->color , box2->color);
136}136}
137 137
138static av_always_inline int diff(const uint32_t a, const uint32_t b)
139{
140 const uint8_t c1[] = {a >> 16 & 0xff, a >> 8 & 0xff, a & 0xff};
141 const uint8_t c2[] = {b >> 16 & 0xff, b >> 8 & 0xff, b & 0xff};
142 const int dr = c1[0] - c2[0];
143 const int dg = c1[1] - c2[1];
144 const int db = c1[2] - c2[2];
145 return dr*dr + dg*dg + db*db;
146}
147
148static void compute_box_stats(PaletteGenContext *s, struct range_box *box)138static void compute_box_stats(PaletteGenContext *s, struct range_box *box)
149{139{
150 int avg[3];140 int avg[3];
@@ -180,6 +170,8 @@ static void compute_box_stats(PaletteGenContext *s, struct range_box *box) · 29 unmodified lines
180 if (er2[2] >= er2[0] && er2[2] >= er2[1]) box->major_axis = 2;170 if (er2[2] >= er2[0] && er2[2] >= er2[1]) box->major_axis = 2;
181 if (er2[0] >= er2[1] && er2[0] >= er2[2]) box->major_axis = 0;171 if (er2[0] >= er2[1] && er2[0] >= er2[2]) box->major_axis = 0;
182 if (er2[1] >= er2[0] && er2[1] >= er2[2]) box->major_axis = 1; // prefer green again172 if (er2[1] >= er2[0] && er2[1] >= er2[2]) box->major_axis = 1; // prefer green again
173
174 box->variance = er2[0] + er2[1] + er2[2];
183}175}
184 176
185/**177/**
@@ -187,7 +179,7 @@ static void compute_box_stats(PaletteGenContext *s, struct range_box *box) · 1 unmodified line
187 */179 */
188static int get_next_box_id_to_split(PaletteGenContext *s)180static int get_next_box_id_to_split(PaletteGenContext *s)
189{181{
190 int box_id, i, best_box_id = -1;182 int box_id, best_box_id = -1;
191 int64_t max_variance = -1;183 int64_t max_variance = -1;
192 184
193 if (s->nb_boxes == s->max_colors - s->reserve_transparent)185 if (s->nb_boxes == s->max_colors - s->reserve_transparent)
@@ -195,24 +187,9 @@ static int get_next_box_id_to_split(PaletteGenContext *s) · 1 unmodified line
195 187
196 for (box_id = 0; box_id < s->nb_boxes; box_id++) {188 for (box_id = 0; box_id < s->nb_boxes; box_id++) {
197 struct range_box *box = &s->boxes[box_id];189 struct range_box *box = &s->boxes[box_id];
198 190 if (s->boxes[box_id].len >= 2 && box->variance > max_variance) {
199 if (s->boxes[box_id].len >= 2) {191 best_box_id = box_id;
200 192 max_variance = box->variance;
201 if (box->variance == -1) {
202 int64_t variance = 0;
203
204 for (i = 0; i < box->len; i++) {
205 const struct color_ref *ref = s->refs[box->start + i];
206 variance += diff(ref->color, box->color) * ref->count;
207 }
208 box->variance = variance;
209 }
210 if (box->variance > max_variance) {
211 best_box_id = box_id;
212 max_variance = box->variance;
213 }
214 } else {
215 box->variance = -1;
216 }193 }
217 }194 }
218 return best_box_id;195 return best_box_id;
@@ -261,8 +238,8 @@ static void split_box(PaletteGenContext *s, struct range_box *box, int n) · 42 unmodified lines
261 238
262 box->color = get_avg_color(s->refs, box);239 box->color = get_avg_color(s->refs, box);
263 new_box->color = get_avg_color(s->refs, new_box);240 new_box->color = get_avg_color(s->refs, new_box);
264 box->variance = -1;241 compute_box_stats(s, box);
265 new_box->variance = -1;242 compute_box_stats(s, new_box);
266}243}
267 244
268/**245/**
@@ -359,14 +336,13 @@ static AVFrame *get_palette_frame(AVFilterContext *ctx) · 90 unmodified lines
359 box->len = s->nb_refs;336 box->len = s->nb_refs;
360 box->sorted_by = -1;337 box->sorted_by = -1;
361 box->color = get_avg_color(s->refs, box);338 box->color = get_avg_color(s->refs, box);
362 box->variance = -1;339 compute_box_stats(s, box);
363 s->nb_boxes = 1;340 s->nb_boxes = 1;
364 341
365 while (box && box->len > 1) {342 while (box && box->len > 1) {
366 int i;343 int i;
367 uint64_t median, box_weight;344 uint64_t median, box_weight;
368 345
369 compute_box_stats(s, box);
370 box_weight = box->weight;346 box_weight = box->weight;
371 347
372 ff_dlog(ctx, "box #%02X [%6d..%-6d] (%6d) w:%-6"PRIu64" sort by %c (already sorted:%c) ",348 ff_dlog(ctx, "box #%02X [%6d..%-6d] (%6d) w:%-6"PRIu64" sort by %c (already sorted:%c) ",

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t