Commit e40e6e57 authored by Aamir Anis's avatar Aamir Anis Committed by Debargha Mukherjee

Tiling in loop restoration + cosmetics

Frame can be split into rectangular tiles for application of separate
bilateral or Wiener filters per tile. Some variable names changed for
better readability.

Change-Id: I13ebc4d0b0baf368e524db5ce276f03ed76af9c8
parent 04ed7ad5
......@@ -82,7 +82,14 @@ void vp10_free_ref_frame_buffers(BufferPool *pool) {
#if CONFIG_LOOP_RESTORATION
void vp10_free_restoration_buffers(VP10_COMMON *cm) {
vpx_free_frame_buffer(&cm->tmp_loop_buf);
vpx_free(cm->rst_info.bilateral_level);
cm->rst_info.bilateral_level = NULL;
vpx_free(cm->rst_info.vfilter);
cm->rst_info.vfilter = NULL;
vpx_free(cm->rst_info.hfilter);
cm->rst_info.hfilter = NULL;
vpx_free(cm->rst_info.wiener_level);
cm->rst_info.wiener_level = NULL;
}
#endif // CONFIG_LOOP_RESTORATION
......
......@@ -1602,7 +1602,10 @@ void vp10_setup_past_independence(VP10_COMMON *cm) {
// To force update of the sharpness
lf->last_sharpness_level = -1;
#if CONFIG_LOOP_RESTORATION
cm->rst_info.restoration_level = -1;
if (cm->rst_info.bilateral_level) {
for (i = 0; i < cm->rst_internal.ntiles; ++i)
cm->rst_info.bilateral_level[i] = -1;
}
#endif // CONFIG_LOOP_RESTORATION
vp10_default_coef_probs(cm);
......
......@@ -168,10 +168,6 @@ typedef struct VP10Common {
int new_fb_idx;
#if CONFIG_LOOP_RESTORATION
YV12_BUFFER_CONFIG tmp_loop_buf;
#endif // CONFIG_LOOP_RESTORATION
FRAME_TYPE last_frame_type; /* last frame's frame type for motion search.*/
#if CONFIG_EXT_REFS
// frame type of the frame before last frame
......
This diff is collapsed.
......@@ -11,8 +11,8 @@
#ifndef VP10_COMMON_RESTORATION_H_
#define VP10_COMMON_RESTORATION_H_
#include "vpx_ports/mem.h"
#include "./vpx_config.h"
#include "vpx_ports/mem.h"
#include "vp10/common/blockd.h"
......@@ -20,11 +20,15 @@
extern "C" {
#endif
#define RESTORATION_LEVEL_BITS_KF 4
#define RESTORATION_LEVELS_KF (1 << RESTORATION_LEVEL_BITS_KF)
#define RESTORATION_LEVEL_BITS 3
#define RESTORATION_LEVELS (1 << RESTORATION_LEVEL_BITS)
#define DEF_RESTORATION_LEVEL 2
#define BILATERAL_LEVEL_BITS_KF 4
#define BILATERAL_LEVELS_KF (1 << BILATERAL_LEVEL_BITS_KF)
#define BILATERAL_LEVEL_BITS 3
#define BILATERAL_LEVELS (1 << BILATERAL_LEVEL_BITS)
// #define DEF_BILATERAL_LEVEL 2
#define RESTORATION_TILESIZES 3
#define BILATERAL_TILESIZE 0
#define WIENER_TILESIZE 2
#define RESTORATION_HALFWIN 3
#define RESTORATION_HALFWIN1 (RESTORATION_HALFWIN + 1)
......@@ -34,9 +38,9 @@ extern "C" {
#define RESTORATION_FILT_BITS 7
#define RESTORATION_FILT_STEP (1 << RESTORATION_FILT_BITS)
#define WIENER_FILT_TAP0_MINV -5
#define WIENER_FILT_TAP0_MINV (-5)
#define WIENER_FILT_TAP1_MINV (-23)
#define WIENER_FILT_TAP2_MINV -20
#define WIENER_FILT_TAP2_MINV (-16)
#define WIENER_FILT_TAP0_BITS 4
#define WIENER_FILT_TAP1_BITS 5
......@@ -60,20 +64,37 @@ typedef enum {
typedef struct {
RestorationType restoration_type;
int restoration_level;
int vfilter[RESTORATION_HALFWIN], hfilter[RESTORATION_HALFWIN];
// Bilateral filter
int *bilateral_level;
// Wiener filter
int *wiener_level;
int (*vfilter)[RESTORATION_HALFWIN], (*hfilter)[RESTORATION_HALFWIN];
} RestorationInfo;
typedef struct {
RestorationType restoration_type;
uint8_t *wx_lut[RESTORATION_WIN];
uint8_t *wr_lut;
int vfilter[RESTORATION_WIN], hfilter[RESTORATION_WIN];
int subsampling_x;
int subsampling_y;
int tilesize_index;
int ntiles;
int tile_width, tile_height;
int nhtiles, nvtiles;
// Bilateral filter
int *bilateral_level;
uint8_t (**wx_lut)[RESTORATION_WIN];
uint8_t **wr_lut;
// Wiener filter
int *wiener_level;
int (*vfilter)[RESTORATION_WIN], (*hfilter)[RESTORATION_WIN];
} RestorationInternal;
int vp10_restoration_level_bits(const struct VP10Common *const cm);
int vp10_bilateral_level_bits(const struct VP10Common *const cm);
int vp10_get_restoration_ntiles(int tilesize, int width, int height);
void vp10_get_restoration_tile_size(int tilesize, int width, int height,
int *tile_width, int *tile_height,
int *nhtiles, int *nvtiles);
void vp10_loop_restoration_init(RestorationInternal *rst, RestorationInfo *rsi,
int kf);
int kf, int width, int height);
void vp10_loop_restoration_frame(YV12_BUFFER_CONFIG *frame,
struct VP10Common *cm, RestorationInfo *rsi,
int y_only, int partial_frame);
......
......@@ -12,12 +12,12 @@
#include <stdlib.h> // qsort()
#include "./vp10_rtcd.h"
#include "./vpx_config.h"
#include "./vpx_dsp_rtcd.h"
#include "./vpx_scale_rtcd.h"
#include "./vpx_config.h"
#include "vpx_dsp/bitreader_buffer.h"
#include "vp10/decoder/bitreader.h"
#include "vpx_dsp/bitreader_buffer.h"
#include "vpx_dsp/vpx_dsp_common.h"
#include "vpx_mem/vpx_mem.h"
#include "vpx_ports/mem.h"
......@@ -36,18 +36,18 @@
#include "vp10/common/entropy.h"
#include "vp10/common/entropymode.h"
#include "vp10/common/idct.h"
#include "vp10/common/thread_common.h"
#include "vp10/common/pred_common.h"
#include "vp10/common/quant_common.h"
#include "vp10/common/reconintra.h"
#include "vp10/common/reconinter.h"
#include "vp10/common/reconintra.h"
#include "vp10/common/seg_common.h"
#include "vp10/common/thread_common.h"
#include "vp10/common/tile_common.h"
#include "vp10/decoder/decodeframe.h"
#include "vp10/decoder/detokenize.h"
#include "vp10/decoder/decodemv.h"
#include "vp10/decoder/decoder.h"
#include "vp10/decoder/detokenize.h"
#include "vp10/decoder/dsubexp.h"
#define MAX_VPX_HEADER_SIZE 80
......@@ -1922,29 +1922,61 @@ static void setup_segmentation(VP10_COMMON *const cm,
#if CONFIG_LOOP_RESTORATION
static void setup_restoration(VP10_COMMON *cm, struct vpx_read_bit_buffer *rb) {
RestorationInfo *rst = &cm->rst_info;
int i;
RestorationInfo *rsi = &cm->rst_info;
int ntiles;
if (vpx_rb_read_bit(rb)) {
if (vpx_rb_read_bit(rb)) {
rsi->restoration_type = RESTORE_BILATERAL;
ntiles = vp10_get_restoration_ntiles(BILATERAL_TILESIZE, cm->width,
cm->height);
rsi->bilateral_level = (int *)vpx_realloc(
rsi->bilateral_level, sizeof(*rsi->bilateral_level) * ntiles);
assert(rsi->bilateral_level != NULL);
for (i = 0; i < ntiles; ++i) {
if (vpx_rb_read_bit(rb)) {
rst->restoration_type = RESTORE_BILATERAL;
rst->restoration_level =
vpx_rb_read_literal(rb, vp10_restoration_level_bits(cm));
rsi->bilateral_level[i] =
vpx_rb_read_literal(rb, vp10_bilateral_level_bits(cm));
} else {
rst->restoration_type = RESTORE_WIENER;
rst->vfilter[0] = vpx_rb_read_literal(rb, WIENER_FILT_TAP0_BITS) +
rsi->bilateral_level[i] = -1;
}
}
} else {
rsi->restoration_type = RESTORE_WIENER;
ntiles =
vp10_get_restoration_ntiles(WIENER_TILESIZE, cm->width, cm->height);
rsi->wiener_level = (int *)vpx_realloc(
rsi->wiener_level, sizeof(*rsi->wiener_level) * ntiles);
assert(rsi->wiener_level != NULL);
rsi->vfilter = (int(*)[RESTORATION_HALFWIN])vpx_realloc(
rsi->vfilter, sizeof(*rsi->vfilter) * ntiles);
assert(rsi->vfilter != NULL);
rsi->hfilter = (int(*)[RESTORATION_HALFWIN])vpx_realloc(
rsi->hfilter, sizeof(*rsi->hfilter) * ntiles);
assert(rsi->hfilter != NULL);
for (i = 0; i < ntiles; ++i) {
rsi->wiener_level[i] = vpx_rb_read_bit(rb);
if (rsi->wiener_level[i]) {
rsi->vfilter[i][0] = vpx_rb_read_literal(rb, WIENER_FILT_TAP0_BITS) +
WIENER_FILT_TAP0_MINV;
rst->vfilter[1] = vpx_rb_read_literal(rb, WIENER_FILT_TAP1_BITS) +
rsi->vfilter[i][1] = vpx_rb_read_literal(rb, WIENER_FILT_TAP1_BITS) +
WIENER_FILT_TAP1_MINV;
rst->vfilter[2] = vpx_rb_read_literal(rb, WIENER_FILT_TAP2_BITS) +
rsi->vfilter[i][2] = vpx_rb_read_literal(rb, WIENER_FILT_TAP2_BITS) +
WIENER_FILT_TAP2_MINV;
rst->hfilter[0] = vpx_rb_read_literal(rb, WIENER_FILT_TAP0_BITS) +
rsi->hfilter[i][0] = vpx_rb_read_literal(rb, WIENER_FILT_TAP0_BITS) +
WIENER_FILT_TAP0_MINV;
rst->hfilter[1] = vpx_rb_read_literal(rb, WIENER_FILT_TAP1_BITS) +
rsi->hfilter[i][1] = vpx_rb_read_literal(rb, WIENER_FILT_TAP1_BITS) +
WIENER_FILT_TAP1_MINV;
rst->hfilter[2] = vpx_rb_read_literal(rb, WIENER_FILT_TAP2_BITS) +
rsi->hfilter[i][2] = vpx_rb_read_literal(rb, WIENER_FILT_TAP2_BITS) +
WIENER_FILT_TAP2_MINV;
} else {
rsi->vfilter[i][0] = rsi->vfilter[i][1] = rsi->vfilter[i][2] = 0;
rsi->hfilter[i][0] = rsi->hfilter[i][1] = rsi->hfilter[i][2] = 0;
}
}
}
} else {
rst->restoration_type = RESTORE_NONE;
rsi->restoration_type = RESTORE_NONE;
}
}
#endif // CONFIG_LOOP_RESTORATION
......@@ -3817,7 +3849,8 @@ void vp10_decode_frame(VP10Decoder *pbi, const uint8_t *data,
#if CONFIG_LOOP_RESTORATION
if (cm->rst_info.restoration_type != RESTORE_NONE) {
vp10_loop_restoration_init(&cm->rst_internal, &cm->rst_info,
cm->frame_type == KEY_FRAME);
cm->frame_type == KEY_FRAME, cm->width,
cm->height);
vp10_loop_restoration_rows(new_fb, cm, 0, cm->mi_rows, 0);
}
#endif // CONFIG_LOOP_RESTORATION
......
......@@ -9,8 +9,8 @@
*/
#include <assert.h>
#include <stdio.h>
#include <limits.h>
#include <stdio.h>
#include "vpx/vpx_encoder.h"
#include "vpx_dsp/bitwriter_buffer.h"
......@@ -38,8 +38,8 @@
#if CONFIG_ANS
#include "vp10/encoder/buf_ans.h"
#endif // CONFIG_ANS
#include "vp10/encoder/cost.h"
#include "vp10/encoder/bitstream.h"
#include "vp10/encoder/cost.h"
#include "vp10/encoder/encodemv.h"
#include "vp10/encoder/mcomp.h"
#include "vp10/encoder/segmentation.h"
......@@ -2410,27 +2410,42 @@ static void update_coef_probs(VP10_COMP *cpi, vp10_writer *w) {
#if CONFIG_LOOP_RESTORATION
static void encode_restoration(VP10_COMMON *cm,
struct vpx_write_bit_buffer *wb) {
int i;
RestorationInfo *rst = &cm->rst_info;
vpx_wb_write_bit(wb, rst->restoration_type != RESTORE_NONE);
if (rst->restoration_type != RESTORE_NONE) {
if (rst->restoration_type == RESTORE_BILATERAL) {
vpx_wb_write_bit(wb, 1);
vpx_wb_write_literal(wb, rst->restoration_level,
vp10_restoration_level_bits(cm));
for (i = 0; i < cm->rst_internal.ntiles; ++i) {
if (rst->bilateral_level[i] >= 0) {
vpx_wb_write_bit(wb, 1);
vpx_wb_write_literal(wb, rst->bilateral_level[i],
vp10_bilateral_level_bits(cm));
} else {
vpx_wb_write_bit(wb, 0);
vpx_wb_write_literal(wb, rst->vfilter[0] - WIENER_FILT_TAP0_MINV,
}
}
} else {
vpx_wb_write_bit(wb, 0);
for (i = 0; i < cm->rst_internal.ntiles; ++i) {
if (rst->wiener_level[i]) {
vpx_wb_write_bit(wb, 1);
vpx_wb_write_literal(wb, rst->vfilter[i][0] - WIENER_FILT_TAP0_MINV,
WIENER_FILT_TAP0_BITS);
vpx_wb_write_literal(wb, rst->vfilter[1] - WIENER_FILT_TAP1_MINV,
vpx_wb_write_literal(wb, rst->vfilter[i][1] - WIENER_FILT_TAP1_MINV,
WIENER_FILT_TAP1_BITS);
vpx_wb_write_literal(wb, rst->vfilter[2] - WIENER_FILT_TAP2_MINV,
vpx_wb_write_literal(wb, rst->vfilter[i][2] - WIENER_FILT_TAP2_MINV,
WIENER_FILT_TAP2_BITS);
vpx_wb_write_literal(wb, rst->hfilter[0] - WIENER_FILT_TAP0_MINV,
vpx_wb_write_literal(wb, rst->hfilter[i][0] - WIENER_FILT_TAP0_MINV,
WIENER_FILT_TAP0_BITS);
vpx_wb_write_literal(wb, rst->hfilter[1] - WIENER_FILT_TAP1_MINV,
vpx_wb_write_literal(wb, rst->hfilter[i][1] - WIENER_FILT_TAP1_MINV,
WIENER_FILT_TAP1_BITS);
vpx_wb_write_literal(wb, rst->hfilter[2] - WIENER_FILT_TAP2_MINV,
vpx_wb_write_literal(wb, rst->hfilter[i][2] - WIENER_FILT_TAP2_MINV,
WIENER_FILT_TAP2_BITS);
} else {
vpx_wb_write_bit(wb, 0);
}
}
}
}
}
......
......@@ -8,9 +8,9 @@
* be found in the AUTHORS file in the root of the source tree.
*/
#include <limits.h>
#include <math.h>
#include <stdio.h>
#include <limits.h>
#include "./vpx_config.h"
......@@ -459,14 +459,12 @@ static void dealloc_compressor_data(VP10_COMP *cpi) {
vpx_free_frame_buffer(&cpi->upsampled_ref_bufs[i].buf);
vp10_free_ref_frame_buffers(cm->buffer_pool);
#if CONFIG_LOOP_RESTORATION
vp10_free_restoration_buffers(cm);
#endif // CONFIG_LOOP_RESTORATION
vp10_free_context_buffers(cm);
vpx_free_frame_buffer(&cpi->last_frame_uf);
#if CONFIG_LOOP_RESTORATION
vpx_free_frame_buffer(&cpi->last_frame_db);
vp10_free_restoration_buffers(cm);
#endif // CONFIG_LOOP_RESTORATION
vpx_free_frame_buffer(&cpi->scaled_source);
vpx_free_frame_buffer(&cpi->scaled_last_source);
......@@ -3492,7 +3490,8 @@ static void loopfilter_frame(VP10_COMP *cpi, VP10_COMMON *cm) {
#if CONFIG_LOOP_RESTORATION
if (cm->rst_info.restoration_type != RESTORE_NONE) {
vp10_loop_restoration_init(&cm->rst_internal, &cm->rst_info,
cm->frame_type == KEY_FRAME);
cm->frame_type == KEY_FRAME, cm->width,
cm->height);
vp10_loop_restoration_rows(cm->frame_to_show, cm, 0, cm->mi_rows, 0);
}
#endif // CONFIG_LOOP_RESTORATION
......
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment