vp9_picklpf.c revision 5ae7ac49f08a179e4f054d99fcfc9dce78d26e58
1ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang/* 2ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * Copyright (c) 2010 The WebM project authors. All Rights Reserved. 3ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * 4ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * Use of this source code is governed by a BSD-style license 5ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * that can be found in the LICENSE file in the root of the source 6ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * tree. An additional intellectual property rights grant can be found 7ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * in the file PATENTS. All contributing project authors may 8ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * be found in the AUTHORS file in the root of the source tree. 9ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang */ 10ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 11ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include <assert.h> 12ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include <limits.h> 13ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "vp9/common/vp9_onyxc_int.h" 14ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "vp9/encoder/vp9_onyx_int.h" 15ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "vp9/encoder/vp9_picklpf.h" 16ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "vp9/encoder/vp9_quantize.h" 17ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "vpx_mem/vpx_mem.h" 18ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "vpx_scale/vpx_scale.h" 19ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "vp9/common/vp9_alloccommon.h" 20ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "vp9/common/vp9_loopfilter.h" 21ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "./vpx_scale_rtcd.h" 22ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 23ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangvoid vp9_yv12_copy_partial_frame_c(YV12_BUFFER_CONFIG *src_ybc, 241184aebb761cbeac9124c37189a80a1a58f04b6bhkuang YV12_BUFFER_CONFIG *dst_ybc, int fraction) { 251184aebb761cbeac9124c37189a80a1a58f04b6bhkuang const int height = src_ybc->y_height; 261184aebb761cbeac9124c37189a80a1a58f04b6bhkuang const int stride = src_ybc->y_stride; 271184aebb761cbeac9124c37189a80a1a58f04b6bhkuang const int offset = stride * ((height >> 5) * 16 - 8); 281184aebb761cbeac9124c37189a80a1a58f04b6bhkuang const int lines_to_copy = MAX(height >> (fraction + 4), 1) << 4; 29ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 30ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang assert(src_ybc->y_stride == dst_ybc->y_stride); 311184aebb761cbeac9124c37189a80a1a58f04b6bhkuang vpx_memcpy(dst_ybc->y_buffer + offset, src_ybc->y_buffer + offset, 321184aebb761cbeac9124c37189a80a1a58f04b6bhkuang stride * (lines_to_copy + 16)); 33ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang} 34ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 35ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstatic int calc_partial_ssl_err(YV12_BUFFER_CONFIG *source, 36ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang YV12_BUFFER_CONFIG *dest, int Fraction) { 37ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang int i, j; 38ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang int Total = 0; 39ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang int srcoffset, dstoffset; 40ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang uint8_t *src = source->y_buffer; 41ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang uint8_t *dst = dest->y_buffer; 42ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 43ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang int linestocopy = (source->y_height >> (Fraction + 4)); 44ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 45ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (linestocopy < 1) 46ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang linestocopy = 1; 47ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 48ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang linestocopy <<= 4; 49ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 50ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 51ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang srcoffset = source->y_stride * (dest->y_height >> 5) * 16; 52ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang dstoffset = dest->y_stride * (dest->y_height >> 5) * 16; 53ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 54ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang src += srcoffset; 55ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang dst += dstoffset; 56ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 575ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang // Loop through the raw Y plane and reconstruction data summing the square 585ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang // differences. 59ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang for (i = 0; i < linestocopy; i += 16) { 60ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang for (j = 0; j < source->y_width; j += 16) { 61ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang unsigned int sse; 62ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Total += vp9_mse16x16(src + j, source->y_stride, dst + j, dest->y_stride, 63ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang &sse); 64ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 65ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 66ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang src += 16 * source->y_stride; 67ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang dst += 16 * dest->y_stride; 68ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 69ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 70ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return Total; 71ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang} 72ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 73ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang// Enforce a minimum filter level based upon baseline Q 74ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstatic int get_min_filter_level(VP9_COMP *cpi, int base_qindex) { 75ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang int min_filter_level; 76ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang min_filter_level = 0; 77ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 78ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return min_filter_level; 79ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang} 80ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 81ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang// Enforce a maximum filter level based upon baseline Q 82ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstatic int get_max_filter_level(VP9_COMP *cpi, int base_qindex) { 835ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang int max_filter_level = MAX_LOOP_FILTER; 84ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang (void)base_qindex; 85ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 86ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (cpi->twopass.section_intra_rating > 8) 87ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang max_filter_level = MAX_LOOP_FILTER * 3 / 4; 88ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 89ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return max_filter_level; 90ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang} 91ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 92ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 93ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang// Stub function for now Alt LF not used 94ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangvoid vp9_set_alt_lf_level(VP9_COMP *cpi, int filt_val) { 95ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang} 96ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 971184aebb761cbeac9124c37189a80a1a58f04b6bhkuangvoid vp9_pick_filter_level(YV12_BUFFER_CONFIG *sd, VP9_COMP *cpi, int partial) { 981184aebb761cbeac9124c37189a80a1a58f04b6bhkuang VP9_COMMON *const cm = &cpi->common; 991184aebb761cbeac9124c37189a80a1a58f04b6bhkuang struct loopfilter *const lf = &cm->lf; 100ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 101ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang int best_err = 0; 102ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang int filt_err = 0; 1031184aebb761cbeac9124c37189a80a1a58f04b6bhkuang const int min_filter_level = get_min_filter_level(cpi, cm->base_qindex); 1041184aebb761cbeac9124c37189a80a1a58f04b6bhkuang const int max_filter_level = get_max_filter_level(cpi, cm->base_qindex); 105ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 106ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang int filter_step; 107ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang int filt_high = 0; 10891037db265ecdd914a26e056cf69207b4f50924ehkuang // Start search at previous frame filter level 10991037db265ecdd914a26e056cf69207b4f50924ehkuang int filt_mid = lf->filter_level; 110ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang int filt_low = 0; 111ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang int filt_best; 112ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang int filt_direction = 0; 113ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1145ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang int Bias = 0; // Bias against raising loop filter in favor of lowering it. 115ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 116ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang // Make a copy of the unfiltered / processed recon buffer 1171184aebb761cbeac9124c37189a80a1a58f04b6bhkuang vpx_yv12_copy_y(cm->frame_to_show, &cpi->last_frame_uf); 118ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1191184aebb761cbeac9124c37189a80a1a58f04b6bhkuang lf->sharpness_level = cm->frame_type == KEY_FRAME ? 0 1201184aebb761cbeac9124c37189a80a1a58f04b6bhkuang : cpi->oxcf.Sharpness; 121ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1225ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang // Start the search at the previous frame filter level unless it is now out of 1235ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang // range. 1241184aebb761cbeac9124c37189a80a1a58f04b6bhkuang filt_mid = clamp(lf->filter_level, min_filter_level, max_filter_level); 125ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 126ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang // Define the initial step size 1271184aebb761cbeac9124c37189a80a1a58f04b6bhkuang filter_step = filt_mid < 16 ? 4 : filt_mid / 4; 128ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 129ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang // Get baseline error score 130ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang vp9_set_alt_lf_level(cpi, filt_mid); 1311184aebb761cbeac9124c37189a80a1a58f04b6bhkuang vp9_loop_filter_frame(cm, &cpi->mb.e_mbd, filt_mid, 1, partial); 132ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 133ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang best_err = vp9_calc_ss_err(sd, cm->frame_to_show); 134ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang filt_best = filt_mid; 135ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 136ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang // Re-instate the unfiltered frame 1371184aebb761cbeac9124c37189a80a1a58f04b6bhkuang vpx_yv12_copy_y(&cpi->last_frame_uf, cm->frame_to_show); 138ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 139ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang while (filter_step > 0) { 1405ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang Bias = (best_err >> (15 - (filt_mid / 8))) * filter_step; 141ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 142ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (cpi->twopass.section_intra_rating < 20) 143ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Bias = Bias * cpi->twopass.section_intra_rating / 20; 144ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 145ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang // yx, bias less for large block size 14691037db265ecdd914a26e056cf69207b4f50924ehkuang if (cpi->common.tx_mode != ONLY_4X4) 147ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Bias >>= 1; 148ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1495ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang filt_high = ((filt_mid + filter_step) > max_filter_level) 1505ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang ? max_filter_level 1515ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang : (filt_mid + filter_step); 1525ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang filt_low = ((filt_mid - filter_step) < min_filter_level) 1535ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang ? min_filter_level 1545ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang : (filt_mid - filter_step); 155ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 156ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if ((filt_direction <= 0) && (filt_low != filt_mid)) { 157ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang // Get Low filter error score 158ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang vp9_set_alt_lf_level(cpi, filt_low); 1591184aebb761cbeac9124c37189a80a1a58f04b6bhkuang vp9_loop_filter_frame(cm, &cpi->mb.e_mbd, filt_low, 1, partial); 160ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 161ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang filt_err = vp9_calc_ss_err(sd, cm->frame_to_show); 162ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 163ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang // Re-instate the unfiltered frame 1641184aebb761cbeac9124c37189a80a1a58f04b6bhkuang vpx_yv12_copy_y(&cpi->last_frame_uf, cm->frame_to_show); 165ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1665ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang // If value is close to the best so far then bias towards a lower loop 1675ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang // filter value. 168ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if ((filt_err - Bias) < best_err) { 169ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang // Was it actually better than the previous best? 170ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (filt_err < best_err) 171ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang best_err = filt_err; 172ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 173ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang filt_best = filt_low; 174ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 175ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 176ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 177ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang // Now look at filt_high 178ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if ((filt_direction >= 0) && (filt_high != filt_mid)) { 179ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang vp9_set_alt_lf_level(cpi, filt_high); 1801184aebb761cbeac9124c37189a80a1a58f04b6bhkuang vp9_loop_filter_frame(cm, &cpi->mb.e_mbd, filt_high, 1, partial); 181ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 182ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang filt_err = vp9_calc_ss_err(sd, cm->frame_to_show); 183ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 184ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang // Re-instate the unfiltered frame 1851184aebb761cbeac9124c37189a80a1a58f04b6bhkuang vpx_yv12_copy_y(&cpi->last_frame_uf, cm->frame_to_show); 186ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 187ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang // Was it better than the previous best? 188ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (filt_err < (best_err - Bias)) { 189ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang best_err = filt_err; 190ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang filt_best = filt_high; 191ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 192ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 193ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 194ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang // Half the step distance if the best filter value was the same as last time 195ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (filt_best == filt_mid) { 196ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang filter_step = filter_step / 2; 197ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang filt_direction = 0; 198ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } else { 199ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang filt_direction = (filt_best < filt_mid) ? -1 : 1; 200ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang filt_mid = filt_best; 201ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 202ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 203ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 20491037db265ecdd914a26e056cf69207b4f50924ehkuang lf->filter_level = filt_best; 205ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang} 206