Mercurial > libavcodec.hg
changeset 2531:eed7d92a1dfc libavcodec
VP3 post-processing loop filter; disabled until the correct final step
is determined
author | melanson |
---|---|
date | Tue, 01 Mar 2005 06:14:45 +0000 |
parents | eace30b70601 |
children | b7511e7dabb7 |
files | vp3.c vp3data.h |
diffstat | 2 files changed, 149 insertions(+), 1 deletions(-) [+] |
line wrap: on
line diff
--- a/vp3.c Tue Mar 01 02:24:58 2005 +0000 +++ b/vp3.c Tue Mar 01 06:14:45 2005 +0000 @@ -2219,7 +2219,143 @@ } emms_c(); - +} + +#define SATURATE_U8(x) ((x) < 0) ? 0 : ((x) > 255) ? 255 : x + +static void horizontal_filter(unsigned char *first_pixel, int stride, + int *bounding_values) +{ + int i; + int filter_value; + + for (i = 0; i < 8; i++, first_pixel += stride) { + filter_value = + (first_pixel[-2] * 1) - + (first_pixel[-1] * 3) + + (first_pixel[ 0] * 3) - + (first_pixel[ 1] * 1); + filter_value = bounding_values[(filter_value + 4) >> 3]; + first_pixel[-1] = SATURATE_U8(first_pixel[-1] + filter_value); + first_pixel[ 0] = SATURATE_U8(first_pixel[ 0] - filter_value); + } +} + +static void vertical_filter(unsigned char *first_pixel, int stride, + int *bounding_values) +{ + int i; + int filter_value; + + for (i = 0; i < 8; i++, first_pixel++) { + filter_value = + (first_pixel[-(2 * stride)] * 1) - + (first_pixel[-(1 * stride)] * 3) + + (first_pixel[ (0 )] * 3) - + (first_pixel[ (1 * stride)] * 1); + filter_value = bounding_values[(filter_value + 4) >> 3]; + first_pixel[-(1 * stride)] = SATURATE_U8(first_pixel[-(1 * stride)] + filter_value); + first_pixel[0] = SATURATE_U8(first_pixel[0] - filter_value); + } +} + +static void apply_loop_filter(Vp3DecodeContext *s) +{ + int x, y, plane; + int width, height; + int fragment; + int stride; + unsigned char *plane_data; + int bounding_values[256]; + int filter_limit; + + /* find the right loop limit value */ + for (x = 63; x >= 0; x--) { + if (vp31_ac_scale_factor[x] >= s->quality_index) + break; + } + filter_limit = vp31_filter_limit_values[x]; + + /* set up the bounding values */ + memset(bounding_values, 0, 256 * sizeof(int)); + for (x = 0; x < filter_limit; x++) { + bounding_values[-x - filter_limit] = -filter_limit + x; + bounding_values[-x] = -x; + bounding_values[x] = x; + bounding_values[x + filter_limit] = filter_limit - x; + } + + for (plane = 0; plane < 3; plane++) { + + if (plane == 0) { + /* Y plane parameters */ + fragment = 0; + width = s->fragment_width; + height = s->fragment_height; + stride = s->current_frame.linesize[0]; + plane_data = s->current_frame.data[0]; + } else if (plane == 1) { + /* U plane parameters */ + fragment = s->u_fragment_start; + width = s->fragment_width / 2; + height = s->fragment_height / 2; + stride = s->current_frame.linesize[1]; + plane_data = s->current_frame.data[1]; + } else { + /* V plane parameters */ + fragment = s->v_fragment_start; + width = s->fragment_width / 2; + height = s->fragment_height / 2; + stride = s->current_frame.linesize[2]; + plane_data = s->current_frame.data[2]; + } + + for (y = 0; y < height; y++) { + + for (x = 0; x < width; x++) { + + /* do not perform left edge filter for left columns frags */ + if ((x > 0) && + (s->all_fragments[fragment].coding_method != MODE_COPY)) { + horizontal_filter( + plane_data + s->all_fragments[fragment].first_pixel, + stride, bounding_values); + } + + /* do not perform top edge filter for top row fragments */ + if ((y > 0) && + (s->all_fragments[fragment].coding_method != MODE_COPY)) { + vertical_filter( + plane_data + s->all_fragments[fragment].first_pixel, + stride, bounding_values); + } + + /* do not perform right edge filter for right column + * fragments or if right fragment neighbor is also coded + * in this frame (it will be filtered in next iteration) */ + if ((x < width - 1) && + (s->all_fragments[fragment].coding_method != MODE_COPY) && + (s->all_fragments[fragment + 1].coding_method == MODE_COPY)) { + horizontal_filter( + plane_data + s->all_fragments[fragment + 1].first_pixel, + stride, bounding_values); + } + + /* do not perform bottom edge filter for bottom row + * fragments or if bottom fragment neighbor is also coded + * in this frame (it will be filtered in the next row) */ + if ((y < height - 1) && + (s->all_fragments[fragment].coding_method != MODE_COPY) && + (s->all_fragments[fragment + width].coding_method == MODE_COPY)) { + vertical_filter( + plane_data + s->all_fragments[fragment + width].first_pixel, + stride, bounding_values); + } + + fragment++; + } + } + } } /* @@ -2601,6 +2737,7 @@ reverse_dc_prediction(s, 0, s->fragment_width, s->fragment_height); render_fragments(s, 0, s->width, s->height, 0); +// apply_loop_filter(s); if ((avctx->flags & CODEC_FLAG_GRAY) == 0) { reverse_dc_prediction(s, s->u_fragment_start,
--- a/vp3data.h Tue Mar 01 02:24:58 2005 +0000 +++ b/vp3data.h Tue Mar 01 06:14:45 2005 +0000 @@ -61,6 +61,17 @@ 21, 19, 18, 17, 15, 13, 12, 10 }; +static const uint32_t vp31_filter_limit_values[64] = +{ 30, 25, 20, 20, 15, 15, 14, 14, + 13, 13, 12, 12, 11, 11, 10, 10, + 9, 9, 8, 8, 7, 7, 7, 7, + 6, 6, 6, 6, 5, 5, 5, 5, + 4, 4, 4, 4, 3, 3, 3, 3, + 2, 2, 2, 2, 2, 2, 2, 2, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 +}; + /* table used to convert natural order <-> zigzag order */ static const int dezigzag_index[64] = { 0, 1, 8, 16, 9, 2, 3, 10,