Add fractional pixel sampling for chroma

This commit is contained in:
Ari Lemmetti 2015-08-10 17:49:31 +03:00
parent 650dd7d840
commit b30f17d4b8
3 changed files with 44 additions and 17 deletions

View file

@ -139,28 +139,17 @@ void inter_recon_lcu(const encoder_state_t * const state, const kvz_picture * co
extend_borders(xpos>>1, ypos>>1, (mv[0]>>2)>>1, (mv[1]>>2)>>1, state->tile->lcu_offset_x * (LCU_WIDTH>>1), state->tile->lcu_offset_y * (LCU_WIDTH>>1),
ref->u, ref->width>>1, ref->height>>1, FILTER_SIZE_C, width_c, width_c, octpel_src_u);
filter_inter_octpel_chroma(state->encoder_control, octpel_src_off_u, width_c+FILTER_SIZE_C, width_c,
width_c, octpel_dst_u, width_c*8, c_off_x, c_off_y);
sample_octpel_chroma_generic(state->encoder_control, octpel_src_off_u, width_c + FILTER_SIZE_C, width_c,
width_c, lcu->rec.u + ((ypos >> 1) % LCU_WIDTH_C)*LCU_WIDTH_C + ((xpos >> 1) % LCU_WIDTH_C), LCU_WIDTH_C, c_off_x, c_off_y, mv);
//Fractional chroma V
extend_borders(xpos>>1, ypos>>1, (mv[0]>>2)>>1, (mv[1]>>2)>>1, state->tile->lcu_offset_x * (LCU_WIDTH>>1), state->tile->lcu_offset_y * (LCU_WIDTH>>1),
ref->v, ref->width>>1, ref->height>>1, FILTER_SIZE_C, width_c, width_c, octpel_src_v);
extend_borders(xpos >> 1, ypos >> 1, (mv[0] >> 2) >> 1, (mv[1] >> 2) >> 1, state->tile->lcu_offset_x * (LCU_WIDTH_C >> 1), state->tile->lcu_offset_y * (LCU_WIDTH_C >> 1),
ref->v, ref->width >> 1, ref->height >> 1, FILTER_SIZE_C, width_c, width_c, octpel_src_v);
filter_inter_octpel_chroma(state->encoder_control, octpel_src_off_v, width_c+FILTER_SIZE_C, width_c,
width_c, octpel_dst_v, width_c*8, c_off_x, c_off_y);
sample_octpel_chroma_generic(state->encoder_control, octpel_src_off_v, width_c + FILTER_SIZE_C, width_c,
width_c, lcu->rec.v + ((ypos >> 1) % LCU_WIDTH_C)*LCU_WIDTH_C + ((xpos >> 1) % LCU_WIDTH_C), LCU_WIDTH_C, c_off_x, c_off_y, mv);
//Sample fractional pixels for chroma
for(y = 0; y < width_c; ++y) {
int y_in_lcu = ((y+(ypos>>1)) & ((LCU_WIDTH>>1)-1));
int qpel_y = y*8+c_off_y;
for(x = 0; x < width_c; ++x) {
int x_in_lcu = ((x+(xpos>>1)) & ((LCU_WIDTH>>1)-1));
int qpel_x = x*8+c_off_x;
lcu->rec.u[y_in_lcu * dst_width_c + x_in_lcu] = (kvz_pixel)octpel_dst_u[qpel_y*(width_c*8)+qpel_x];
lcu->rec.v[y_in_lcu * dst_width_c + x_in_lcu] = (kvz_pixel)octpel_dst_v[qpel_y*(width_c*8)+qpel_x];
}
}
}
mv[0] >>= 2;

View file

@ -383,6 +383,41 @@ void filter_inter_octpel_chroma_generic(const encoder_control_t * const encoder,
}
}
void sample_octpel_chroma_generic(const encoder_control_t * const encoder, kvz_pixel *src, int16_t src_stride, int width, int height,kvz_pixel *dst, int16_t dst_stride, int8_t hor_flag, int8_t ver_flag, const int16_t mv[2])
{
//TODO: horizontal and vertical only filtering
int32_t x, y;
int16_t shift1 = KVZ_BIT_DEPTH - 8;
int32_t shift2 = 6;
int32_t shift3 = 14 - KVZ_BIT_DEPTH;
int32_t offset23 = 1 << (shift2 + shift3 - 1);
int8_t *hor_filter = g_chroma_filter[mv[0] & 7];
int8_t *ver_filter = g_chroma_filter[mv[1] & 7];
#define FILTER_SIZE_C (FILTER_SIZE / 2)
#define FILTER_OFFSET_C (FILTER_OFFSET / 2)
int16_t flipped_hor_filtered[(LCU_WIDTH_C + 1) + FILTER_SIZE_C][(LCU_WIDTH_C + 1) + FILTER_SIZE_C];
// Filter horizontally and flip x and y
for (x = 0; x < width; ++x) {
for (y = 0; y < height + FILTER_SIZE_C; ++y) {
int ypos = y - FILTER_OFFSET_C;
int xpos = x - FILTER_OFFSET_C;
flipped_hor_filtered[x][y] = four_tap_filter_hor_generic(hor_filter, &src[src_stride*ypos + xpos]) >> shift1;
}
}
// Filter vertically and flip x and y
for (x = 0; x < width; ++x) {
for (y = 0; y < height; ++y) {
int ypos = y;
int xpos = x;
dst[y*dst_stride + x] = fast_clip_32bit_to_pixel(((four_tap_filter_hor_16bit_generic(ver_filter, &flipped_hor_filtered[xpos][ypos]) + offset23) >> shift2) >> shift3);
}
}
}
void extend_borders_generic(int xpos, int ypos, int mv_x, int mv_y, int off_x, int off_y, kvz_pixel *ref, int ref_width, int ref_height,
int filterSize, int width, int height, kvz_pixel *dst) {

View file

@ -22,6 +22,9 @@
#include "encoder.h"
int strategy_register_ipol_generic(void* opaque);
//TODO: create strategies from sample functions
void sample_quarterpel_luma_generic(const encoder_control_t * const encoder, kvz_pixel *src, int16_t src_stride, int width, int height, kvz_pixel *dst, int16_t dst_stride, int8_t hor_flag, int8_t ver_flag, const int16_t mv[2]);
void sample_octpel_chroma_generic(const encoder_control_t * const encoder, kvz_pixel *src, int16_t src_stride, int width, int height, kvz_pixel *dst, int16_t dst_stride, int8_t hor_flag, int8_t ver_flag, const int16_t mv[2]);
#endif //STRATEGIES_IPOL_GENERIC_H_